diff --git a/src/Ardalis.SharedKernel/Ardalis.SharedKernel.csproj b/src/Ardalis.SharedKernel/Ardalis.SharedKernel.csproj index 3e55e32..29fb101 100644 --- a/src/Ardalis.SharedKernel/Ardalis.SharedKernel.csproj +++ b/src/Ardalis.SharedKernel/Ardalis.SharedKernel.csproj @@ -13,10 +13,9 @@ https://github.com/ardalis/Ardalis.SharedKernel DDD;Shared Kernel;SharedKernel;Domain-Driven Design;Repository;Specification;ValueObject;Value Object;Ardalis;Clean;Clean Architecture;Clean Architecture Template icon.png - 4.0.0 + 4.1.0 - * Swapped out MediatR for Mediator Souregenerator and Mediator.Abstractions - * Updated dependencies to latest versions + * Added IDomainEvent and related interfaces true true diff --git a/src/Ardalis.SharedKernel/DomainEventBase.cs b/src/Ardalis.SharedKernel/DomainEventBase.cs index 879d490..a86c3b2 100644 --- a/src/Ardalis.SharedKernel/DomainEventBase.cs +++ b/src/Ardalis.SharedKernel/DomainEventBase.cs @@ -1,12 +1,10 @@ -using Mediator; - -namespace Ardalis.SharedKernel; +namespace Ardalis.SharedKernel; /// /// A base type for domain events. Depends on Mediator INotification. /// Includes DateOccurred which is set on creation. /// -public abstract class DomainEventBase : INotification +public abstract class DomainEventBase : IDomainEvent { public DateTime DateOccurred { get; protected set; } = DateTime.UtcNow; } diff --git a/src/Ardalis.SharedKernel/HasDomainEventsBase.cs b/src/Ardalis.SharedKernel/HasDomainEventsBase.cs index e840cdc..7212443 100644 --- a/src/Ardalis.SharedKernel/HasDomainEventsBase.cs +++ b/src/Ardalis.SharedKernel/HasDomainEventsBase.cs @@ -4,9 +4,9 @@ namespace Ardalis.SharedKernel; public abstract class HasDomainEventsBase : IHasDomainEvents { - private readonly List _domainEvents = new(); + private readonly List _domainEvents = new(); [NotMapped] - public IReadOnlyCollection DomainEvents => _domainEvents.AsReadOnly(); + public IReadOnlyCollection DomainEvents => _domainEvents.AsReadOnly(); protected void RegisterDomainEvent(DomainEventBase domainEvent) => _domainEvents.Add(domainEvent); public void ClearDomainEvents() => _domainEvents.Clear(); diff --git a/src/Ardalis.SharedKernel/IDomainEvent.cs b/src/Ardalis.SharedKernel/IDomainEvent.cs new file mode 100644 index 0000000..1e95352 --- /dev/null +++ b/src/Ardalis.SharedKernel/IDomainEvent.cs @@ -0,0 +1,8 @@ +using Mediator; + +namespace Ardalis.SharedKernel; + +public interface IDomainEvent : INotification +{ + DateTime DateOccurred { get; } +} diff --git a/src/Ardalis.SharedKernel/IDomainEventHandler.cs b/src/Ardalis.SharedKernel/IDomainEventHandler.cs new file mode 100644 index 0000000..a03fd1b --- /dev/null +++ b/src/Ardalis.SharedKernel/IDomainEventHandler.cs @@ -0,0 +1,7 @@ +using Mediator; + +namespace Ardalis.SharedKernel; + +public interface IDomainEventHandler : INotificationHandler where T : IDomainEvent +{ +} diff --git a/src/Ardalis.SharedKernel/IHasDomainEvents.cs b/src/Ardalis.SharedKernel/IHasDomainEvents.cs index 9510326..af610b7 100644 --- a/src/Ardalis.SharedKernel/IHasDomainEvents.cs +++ b/src/Ardalis.SharedKernel/IHasDomainEvents.cs @@ -2,6 +2,6 @@ public interface IHasDomainEvents { - IReadOnlyCollection DomainEvents { get; } + IReadOnlyCollection DomainEvents { get; } void ClearDomainEvents(); } diff --git a/src/Ardalis.SharedKernel/MediatRDomainEventDispatcher.cs b/src/Ardalis.SharedKernel/MediatorDomainEventDispatcher.cs similarity index 88% rename from src/Ardalis.SharedKernel/MediatRDomainEventDispatcher.cs rename to src/Ardalis.SharedKernel/MediatorDomainEventDispatcher.cs index 0ea5caf..9907a40 100644 --- a/src/Ardalis.SharedKernel/MediatRDomainEventDispatcher.cs +++ b/src/Ardalis.SharedKernel/MediatorDomainEventDispatcher.cs @@ -20,10 +20,10 @@ public async Task DispatchAndClearEvents(IEnumerable entitiesW { if (entity is IHasDomainEvents hasDomainEvents) { - DomainEventBase[] events = hasDomainEvents.DomainEvents.ToArray(); + IDomainEvent[] events = hasDomainEvents.DomainEvents.ToArray(); hasDomainEvents.ClearDomainEvents(); - foreach (DomainEventBase domainEvent in events) + foreach (var domainEvent in events) await _mediator.Publish(domainEvent).ConfigureAwait(false); } else diff --git a/src/Ardalis.SharedKernel/ValueObject.cs b/src/Ardalis.SharedKernel/ValueObject.cs index 59d0f89..8e244ee 100644 --- a/src/Ardalis.SharedKernel/ValueObject.cs +++ b/src/Ardalis.SharedKernel/ValueObject.cs @@ -4,6 +4,8 @@ /// NOTE: Use `readonly record struct` for most cases in C# 10+ /// See: https://nietras.com/2021/06/14/csharp-10-record-struct/ /// +/// Alternately consider using Vogen +/// /// For this class implementation, reference: /// See: https://enterprisecraftsmanship.com/posts/value-object-better-implementation/ /// diff --git a/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEvents.cs b/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEvents.cs index 8dcd113..20a46a4 100644 --- a/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEvents.cs +++ b/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEvents.cs @@ -4,7 +4,7 @@ namespace Ardalis.SharedKernel.UnitTests.MediatorDomainEventDispatcherTests; -public class DispatchAndClearEvents : INotificationHandler +public class DispatchAndClearEvents : IDomainEventHandler { public class TestDomainEvent : DomainEventBase { } private class TestEntity : EntityBase @@ -29,7 +29,7 @@ public async Task CallsPublishAndClearDomainEvents() await domainEventDispatcher.DispatchAndClearEvents(new List { entity }); // Assert - mediatorMock.Verify(m => m.Publish(It.IsAny(), It.IsAny()), Times.Once); + mediatorMock.Verify(m => m.Publish(It.IsAny(), It.IsAny()), Times.Once); entity.DomainEvents.Should().BeEmpty(); } diff --git a/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEventsWithGuidId.cs b/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEventsWithGuidId.cs index 69151e1..3889906 100644 --- a/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEventsWithGuidId.cs +++ b/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEventsWithGuidId.cs @@ -5,7 +5,7 @@ namespace Ardalis.SharedKernel.UnitTests.MediatRDomainEventDispatcherTests; -public class DispatchAndClearEventsWithGuidId : INotificationHandler +public class DispatchAndClearEventsWithGuidId : IDomainEventHandler { public class TestDomainEvent : DomainEventBase { } private class TestEntity : EntityBase @@ -30,7 +30,7 @@ public async Task CallsPublishAndClearDomainEvents() await domainEventDispatcher.DispatchAndClearEvents(new List> { entity }); // Assert - mediatorMock.Verify(m => m.Publish(It.IsAny(), It.IsAny()), Times.Once); + mediatorMock.Verify(m => m.Publish(It.IsAny(), It.IsAny()), Times.Once); entity.DomainEvents.Should().BeEmpty(); } diff --git a/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEventsWithMixedIds.cs b/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEventsWithMixedIds.cs index b101869..6b7d283 100644 --- a/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEventsWithMixedIds.cs +++ b/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEventsWithMixedIds.cs @@ -5,7 +5,7 @@ namespace Ardalis.SharedKernel.UnitTests.MediatRDomainEventDispatcherTests; -public class DispatchAndClearEventsWithMixedIds : INotificationHandler +public class DispatchAndClearEventsWithMixedIds : IDomainEventHandler { public class TestDomainEvent : DomainEventBase { } public readonly record struct StronglyTyped { } @@ -52,7 +52,7 @@ public async Task CallsPublishAndClearDomainEventsWithStronglyTypedId() await domainEventDispatcher.DispatchAndClearEvents(new List { entity, entityGuid, entityStronglyTyped }); // Assert - mediatorMock.Verify(m => m.Publish(It.IsAny(), It.IsAny()), Times.Exactly(3)); + mediatorMock.Verify(m => m.Publish(It.IsAny(), It.IsAny()), Times.Exactly(3)); entity.DomainEvents.Should().BeEmpty(); entityGuid.DomainEvents.Should().BeEmpty(); entityStronglyTyped.DomainEvents.Should().BeEmpty(); diff --git a/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEventsWithStronglyTypedIds.cs b/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEventsWithStronglyTypedIds.cs index 56d7035..aa3ba8b 100644 --- a/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEventsWithStronglyTypedIds.cs +++ b/tests/Ardalis.SharedKernel.UnitTests/MediatorDomainEventDispatcherTests/DispatchAndClearEventsWithStronglyTypedIds.cs @@ -5,7 +5,7 @@ namespace Ardalis.SharedKernel.UnitTests.MediatRDomainEventDispatcherTests; -public class DispatchAndClearEventsWithStronglyTypedIds : INotificationHandler +public class DispatchAndClearEventsWithStronglyTypedIds : IDomainEventHandler { public class TestDomainEvent : DomainEventBase { } @@ -34,7 +34,7 @@ public async Task CallsPublishAndClearDomainEventsWithStronglyTypedId() await domainEventDispatcher.DispatchAndClearEvents(new List { entity }); // Assert - mediatorMock.Verify(m => m.Publish(It.IsAny(), It.IsAny()), Times.Once); + mediatorMock.Verify(m => m.Publish(It.IsAny(), It.IsAny()), Times.Once); entity.DomainEvents.Should().BeEmpty(); }