Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/Ardalis.SharedKernel/Ardalis.SharedKernel.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
<RepositoryUrl>https://github.com/ardalis/Ardalis.SharedKernel</RepositoryUrl>
<PackageTags>DDD;Shared Kernel;SharedKernel;Domain-Driven Design;Repository;Specification;ValueObject;Value Object;Ardalis;Clean;Clean Architecture;Clean Architecture Template</PackageTags>
<PackageIcon>icon.png</PackageIcon>
<Version>4.0.0</Version>
<Version>4.1.0</Version>
<PackageReleaseNotes>
* Swapped out MediatR for Mediator Souregenerator and Mediator.Abstractions
* Updated dependencies to latest versions
* Added IDomainEvent and related interfaces
</PackageReleaseNotes>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
Expand Down
6 changes: 2 additions & 4 deletions src/Ardalis.SharedKernel/DomainEventBase.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
using Mediator;

namespace Ardalis.SharedKernel;
namespace Ardalis.SharedKernel;

/// <summary>
/// A base type for domain events. Depends on Mediator INotification.
/// Includes DateOccurred which is set on creation.
/// </summary>
public abstract class DomainEventBase : INotification
public abstract class DomainEventBase : IDomainEvent
{
public DateTime DateOccurred { get; protected set; } = DateTime.UtcNow;
}
4 changes: 2 additions & 2 deletions src/Ardalis.SharedKernel/HasDomainEventsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ namespace Ardalis.SharedKernel;

public abstract class HasDomainEventsBase : IHasDomainEvents
{
private readonly List<DomainEventBase> _domainEvents = new();
private readonly List<IDomainEvent> _domainEvents = new();
[NotMapped]
public IReadOnlyCollection<DomainEventBase> DomainEvents => _domainEvents.AsReadOnly();
public IReadOnlyCollection<IDomainEvent> DomainEvents => _domainEvents.AsReadOnly();

protected void RegisterDomainEvent(DomainEventBase domainEvent) => _domainEvents.Add(domainEvent);
public void ClearDomainEvents() => _domainEvents.Clear();
Expand Down
8 changes: 8 additions & 0 deletions src/Ardalis.SharedKernel/IDomainEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Mediator;

namespace Ardalis.SharedKernel;

public interface IDomainEvent : INotification
{
DateTime DateOccurred { get; }
}
7 changes: 7 additions & 0 deletions src/Ardalis.SharedKernel/IDomainEventHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Mediator;

namespace Ardalis.SharedKernel;

public interface IDomainEventHandler<T> : INotificationHandler<T> where T : IDomainEvent
{
}
2 changes: 1 addition & 1 deletion src/Ardalis.SharedKernel/IHasDomainEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

public interface IHasDomainEvents
{
IReadOnlyCollection<DomainEventBase> DomainEvents { get; }
IReadOnlyCollection<IDomainEvent> DomainEvents { get; }
void ClearDomainEvents();
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ public async Task DispatchAndClearEvents(IEnumerable<IHasDomainEvents> 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
Expand Down
2 changes: 2 additions & 0 deletions src/Ardalis.SharedKernel/ValueObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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/
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Ardalis.SharedKernel.UnitTests.MediatorDomainEventDispatcherTests;

public class DispatchAndClearEvents : INotificationHandler<DispatchAndClearEvents.TestDomainEvent>
public class DispatchAndClearEvents : IDomainEventHandler<DispatchAndClearEvents.TestDomainEvent>
{
public class TestDomainEvent : DomainEventBase { }
private class TestEntity : EntityBase
Expand All @@ -29,7 +29,7 @@ public async Task CallsPublishAndClearDomainEvents()
await domainEventDispatcher.DispatchAndClearEvents(new List<EntityBase> { entity });

// Assert
mediatorMock.Verify(m => m.Publish(It.IsAny<DomainEventBase>(), It.IsAny<CancellationToken>()), Times.Once);
mediatorMock.Verify(m => m.Publish(It.IsAny<IDomainEvent>(), It.IsAny<CancellationToken>()), Times.Once);
entity.DomainEvents.Should().BeEmpty();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Ardalis.SharedKernel.UnitTests.MediatRDomainEventDispatcherTests;

public class DispatchAndClearEventsWithGuidId : INotificationHandler<DispatchAndClearEventsWithGuidId.TestDomainEvent>
public class DispatchAndClearEventsWithGuidId : IDomainEventHandler<DispatchAndClearEventsWithGuidId.TestDomainEvent>
{
public class TestDomainEvent : DomainEventBase { }
private class TestEntity : EntityBase<Guid>
Expand All @@ -30,7 +30,7 @@ public async Task CallsPublishAndClearDomainEvents()
await domainEventDispatcher.DispatchAndClearEvents(new List<EntityBase<Guid>> { entity });

// Assert
mediatorMock.Verify(m => m.Publish(It.IsAny<DomainEventBase>(), It.IsAny<CancellationToken>()), Times.Once);
mediatorMock.Verify(m => m.Publish(It.IsAny<IDomainEvent>(), It.IsAny<CancellationToken>()), Times.Once);
entity.DomainEvents.Should().BeEmpty();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Ardalis.SharedKernel.UnitTests.MediatRDomainEventDispatcherTests;

public class DispatchAndClearEventsWithMixedIds : INotificationHandler<DispatchAndClearEventsWithMixedIds.TestDomainEvent>
public class DispatchAndClearEventsWithMixedIds : IDomainEventHandler<DispatchAndClearEventsWithMixedIds.TestDomainEvent>
{
public class TestDomainEvent : DomainEventBase { }
public readonly record struct StronglyTyped { }
Expand Down Expand Up @@ -52,7 +52,7 @@ public async Task CallsPublishAndClearDomainEventsWithStronglyTypedId()
await domainEventDispatcher.DispatchAndClearEvents(new List<IHasDomainEvents> { entity, entityGuid, entityStronglyTyped });

// Assert
mediatorMock.Verify(m => m.Publish(It.IsAny<DomainEventBase>(), It.IsAny<CancellationToken>()), Times.Exactly(3));
mediatorMock.Verify(m => m.Publish(It.IsAny<IDomainEvent>(), It.IsAny<CancellationToken>()), Times.Exactly(3));
entity.DomainEvents.Should().BeEmpty();
entityGuid.DomainEvents.Should().BeEmpty();
entityStronglyTyped.DomainEvents.Should().BeEmpty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Ardalis.SharedKernel.UnitTests.MediatRDomainEventDispatcherTests;

public class DispatchAndClearEventsWithStronglyTypedIds : INotificationHandler<DispatchAndClearEventsWithStronglyTypedIds.TestDomainEvent>
public class DispatchAndClearEventsWithStronglyTypedIds : IDomainEventHandler<DispatchAndClearEventsWithStronglyTypedIds.TestDomainEvent>
{
public class TestDomainEvent : DomainEventBase { }

Expand Down Expand Up @@ -34,7 +34,7 @@ public async Task CallsPublishAndClearDomainEventsWithStronglyTypedId()
await domainEventDispatcher.DispatchAndClearEvents(new List<IHasDomainEvents> { entity });

// Assert
mediatorMock.Verify(m => m.Publish(It.IsAny<DomainEventBase>(), It.IsAny<CancellationToken>()), Times.Once);
mediatorMock.Verify(m => m.Publish(It.IsAny<IDomainEvent>(), It.IsAny<CancellationToken>()), Times.Once);
entity.DomainEvents.Should().BeEmpty();
}

Expand Down