From 2bbaaf5fe08b104dd53a6a1586641d6f0051fbb9 Mon Sep 17 00:00:00 2001 From: adimiko Date: Thu, 10 Apr 2025 20:56:42 +0200 Subject: [PATCH] Added aggragate id in domain event context --- .../EasyWay.EntityFrameworkCore/Extnsions.cs | 7 +- .../EntityFrameworkAggregateRootsContext.cs | 25 ----- .../DomainEvents/DomainEventsAccessor.cs | 35 ------- .../EntityFrameworkEntitiesContext.cs | 16 ++++ source/EasyWay/Entity.cs | 3 +- .../AggregateRoots/ConcurrencyTokenUpdater.cs | 13 +-- .../AggregateRoots/IAggregateRootsContext.cs | 7 -- .../Assemblies/EntitiesFieldsInfo.cs | 26 ++++++ .../Internals/Assemblies/Extensions.cs | 19 ++++ .../AggrageteRootIdSearcher.cs | 91 +++++++++++++++++++ .../EntityStructureInDomain.cs | 45 +++++++++ .../NotFoundAggragateIdForDomainEvent.cs | 7 ++ ...lationshipsBetweenEntityAndAggragaeRoot.cs | 10 ++ .../DomainEvents/DomainEventContext.cs | 4 +- .../DomainEventContextDispacher.cs | 4 +- .../DomainEvents/DomainEventPublisher.cs | 14 ++- .../DomainEvents/DomainEventsAccessor.cs | 32 +++++++ .../Internals/DomainEvents/Extensions.cs | 11 ++- ...ntsContext.cs => IDomainEventsAccessor.cs} | 2 +- .../DomainEvents/IEntitiesContext.cs | 9 ++ source/EasyWay/Internals/Extensions.cs | 2 + 21 files changed, 292 insertions(+), 90 deletions(-) delete mode 100644 source/EasyWay.EntityFrameworkCore/Internals/AggregateRoots/EntityFrameworkAggregateRootsContext.cs delete mode 100644 source/EasyWay.EntityFrameworkCore/Internals/DomainEvents/DomainEventsAccessor.cs create mode 100644 source/EasyWay.EntityFrameworkCore/Internals/Entities/EntityFrameworkEntitiesContext.cs delete mode 100644 source/EasyWay/Internals/AggregateRoots/IAggregateRootsContext.cs create mode 100644 source/EasyWay/Internals/Assemblies/EntitiesFieldsInfo.cs create mode 100644 source/EasyWay/Internals/Assemblies/Extensions.cs create mode 100644 source/EasyWay/Internals/DomainEvents/AggragateRootIds/AggrageteRootIdSearcher.cs create mode 100644 source/EasyWay/Internals/DomainEvents/AggragateRootIds/EntityStructureInDomain.cs create mode 100644 source/EasyWay/Internals/DomainEvents/AggragateRootIds/NotFoundAggragateIdForDomainEvent.cs create mode 100644 source/EasyWay/Internals/DomainEvents/AggragateRootIds/RelationshipsBetweenEntityAndAggragaeRoot.cs create mode 100644 source/EasyWay/Internals/DomainEvents/DomainEventsAccessor.cs rename source/EasyWay/Internals/DomainEvents/{IDomainEventsContext.cs => IDomainEventsAccessor.cs} (78%) create mode 100644 source/EasyWay/Internals/DomainEvents/IEntitiesContext.cs diff --git a/source/EasyWay.EntityFrameworkCore/Extnsions.cs b/source/EasyWay.EntityFrameworkCore/Extnsions.cs index 17bbd3f..36ff8fc 100644 --- a/source/EasyWay.EntityFrameworkCore/Extnsions.cs +++ b/source/EasyWay.EntityFrameworkCore/Extnsions.cs @@ -1,5 +1,5 @@ -using EasyWay.Internals.AggregateRoots; -using EasyWay.Internals.DomainEvents; +using EasyWay.Internals.DomainEvents; +using EasyWay.Internals.Entities; using EasyWay.Internals.Repositories; using EasyWay.Internals.Transactions; using Microsoft.EntityFrameworkCore; @@ -18,8 +18,7 @@ public static void AddEntityFrameworkCore( services.AddScoped((Func)(sp => sp.GetRequiredService())); - services.AddScoped(); - services.AddTransient(); + services.AddScoped(); services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>)); diff --git a/source/EasyWay.EntityFrameworkCore/Internals/AggregateRoots/EntityFrameworkAggregateRootsContext.cs b/source/EasyWay.EntityFrameworkCore/Internals/AggregateRoots/EntityFrameworkAggregateRootsContext.cs deleted file mode 100644 index 4f3fab4..0000000 --- a/source/EasyWay.EntityFrameworkCore/Internals/AggregateRoots/EntityFrameworkAggregateRootsContext.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.EntityFrameworkCore; - -namespace EasyWay.Internals.AggregateRoots -{ - internal sealed class EntityFrameworkAggregateRootsContext : IAggregateRootsContext - { - private readonly DbContext _dbContext; - - public EntityFrameworkAggregateRootsContext(DbContext dbContext) - { - _dbContext = dbContext; - } - - public IReadOnlyCollection GetAggregateRoots() - { - var aggregateRoots = _dbContext - .ChangeTracker - .Entries() - .Select(x => x.Entity) - .ToList(); - - return aggregateRoots; - } - } -} diff --git a/source/EasyWay.EntityFrameworkCore/Internals/DomainEvents/DomainEventsAccessor.cs b/source/EasyWay.EntityFrameworkCore/Internals/DomainEvents/DomainEventsAccessor.cs deleted file mode 100644 index 735e253..0000000 --- a/source/EasyWay.EntityFrameworkCore/Internals/DomainEvents/DomainEventsAccessor.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Microsoft.EntityFrameworkCore; - -namespace EasyWay.Internals.DomainEvents -{ - internal sealed class DomainEventsAccessor : IDomainEventsContext - { - private readonly DbContext _dbContext; - - public DomainEventsAccessor(DbContext dbContext) - { - _dbContext = dbContext; - } - - public IReadOnlyCollection GetAllDomainEvents() - { - var domainEntities = _dbContext.ChangeTracker - .Entries() - .Where(x => x.Entity.DomainEvents != null && x.Entity.DomainEvents.Any()).ToList(); - - return domainEntities - .SelectMany(x => x.Entity.DomainEvents) - .ToList(); - } - - public void ClearAllDomainEvents() - { - var domainEntities = _dbContext.ChangeTracker - .Entries() - .Where(x => x.Entity.DomainEvents != null && x.Entity.DomainEvents.Any()).ToList(); - - domainEntities - .ForEach(entity => entity.Entity.ClearDomainEvents()); - } - } -} diff --git a/source/EasyWay.EntityFrameworkCore/Internals/Entities/EntityFrameworkEntitiesContext.cs b/source/EasyWay.EntityFrameworkCore/Internals/Entities/EntityFrameworkEntitiesContext.cs new file mode 100644 index 0000000..705ee29 --- /dev/null +++ b/source/EasyWay.EntityFrameworkCore/Internals/Entities/EntityFrameworkEntitiesContext.cs @@ -0,0 +1,16 @@ +using EasyWay.Internals.DomainEvents; +using Microsoft.EntityFrameworkCore; + +namespace EasyWay.Internals.Entities +{ + internal sealed class EntityFrameworkEntitiesContext : IEntitiesContext + { + private readonly DbContext _dbContext; + + public EntityFrameworkEntitiesContext(DbContext dbContext) => _dbContext = dbContext; + + public IEnumerable GetAggregateRoots() => _dbContext.ChangeTracker.Entries().Select(x => x.Entity); + + public IEnumerable GetEntities() => _dbContext.ChangeTracker.Entries().Select(x => x.Entity); + } +} diff --git a/source/EasyWay/Entity.cs b/source/EasyWay/Entity.cs index 3019acc..fb3c0ce 100644 --- a/source/EasyWay/Entity.cs +++ b/source/EasyWay/Entity.cs @@ -37,8 +37,7 @@ protected void Add(TDomainEvent domainEvent) var domainEventContext = new DomainEventContext() { EventId = GuidGenerator.New, - AggragetRootId = Id, // TODO what when we have object graph - EntityId = Id, + Entity = this, OccurrenceOnUtc = InternalClock.UtcNow, DomainEvent = domainEvent, }; diff --git a/source/EasyWay/Internals/AggregateRoots/ConcurrencyTokenUpdater.cs b/source/EasyWay/Internals/AggregateRoots/ConcurrencyTokenUpdater.cs index f1f9e7f..76aa1f4 100644 --- a/source/EasyWay/Internals/AggregateRoots/ConcurrencyTokenUpdater.cs +++ b/source/EasyWay/Internals/AggregateRoots/ConcurrencyTokenUpdater.cs @@ -1,18 +1,19 @@ -namespace EasyWay.Internals.AggregateRoots +using EasyWay.Internals.DomainEvents; + +namespace EasyWay.Internals.AggregateRoots { internal sealed class ConcurrencyTokenUpdater { - private readonly IAggregateRootsContext _aggragateRootsContext; + private readonly IEntitiesContext _context; - public ConcurrencyTokenUpdater( - IAggregateRootsContext aggragateRootsContext) + public ConcurrencyTokenUpdater(IEntitiesContext context) { - _aggragateRootsContext = aggragateRootsContext; + _context = context; } public void Update() { - var aggragateRoots = _aggragateRootsContext.GetAggregateRoots(); + var aggragateRoots = _context.GetAggregateRoots(); foreach (var aggragateRoot in aggragateRoots) { diff --git a/source/EasyWay/Internals/AggregateRoots/IAggregateRootsContext.cs b/source/EasyWay/Internals/AggregateRoots/IAggregateRootsContext.cs deleted file mode 100644 index 0880397..0000000 --- a/source/EasyWay/Internals/AggregateRoots/IAggregateRootsContext.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace EasyWay.Internals.AggregateRoots -{ - internal interface IAggregateRootsContext - { - IReadOnlyCollection GetAggregateRoots(); - } -} diff --git a/source/EasyWay/Internals/Assemblies/EntitiesFieldsInfo.cs b/source/EasyWay/Internals/Assemblies/EntitiesFieldsInfo.cs new file mode 100644 index 0000000..0d67e9c --- /dev/null +++ b/source/EasyWay/Internals/Assemblies/EntitiesFieldsInfo.cs @@ -0,0 +1,26 @@ +using System.Collections.ObjectModel; +using System.Reflection; + +namespace EasyWay.Internals.Assemblies +{ + internal sealed class EntitiesFieldsInfo + { + internal static ReadOnlyDictionary Dictionary; + + internal EntitiesFieldsInfo(IEnumerable types) + { + var dictionary = new Dictionary(); + + var aggregateRootTypes = types.Where(x => x.IsSubclassOf(typeof(AggregateRoot))); + + foreach (var aggregateRootType in aggregateRootTypes) + { + var fields = aggregateRootType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); + + dictionary.Add(aggregateRootType, fields); + } + + Dictionary = new ReadOnlyDictionary(dictionary); + } + } +} diff --git a/source/EasyWay/Internals/Assemblies/Extensions.cs b/source/EasyWay/Internals/Assemblies/Extensions.cs new file mode 100644 index 0000000..1289a07 --- /dev/null +++ b/source/EasyWay/Internals/Assemblies/Extensions.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.DependencyInjection; +using System.Reflection; + +namespace EasyWay.Internals.Assemblies +{ + internal static class Extensions + { + internal static IServiceCollection AddAssemblies( + this IServiceCollection services, + IEnumerable assemblies) + { + var types = assemblies.SelectMany(x => x.GetTypes()).Distinct(); + + new EntitiesFieldsInfo(types); + + return services; + } + } +} diff --git a/source/EasyWay/Internals/DomainEvents/AggragateRootIds/AggrageteRootIdSearcher.cs b/source/EasyWay/Internals/DomainEvents/AggragateRootIds/AggrageteRootIdSearcher.cs new file mode 100644 index 0000000..502ce9a --- /dev/null +++ b/source/EasyWay/Internals/DomainEvents/AggragateRootIds/AggrageteRootIdSearcher.cs @@ -0,0 +1,91 @@ +using EasyWay.Internals.Assemblies; +using System.Collections; +using System.Reflection; + +namespace EasyWay.Internals.DomainEvents.AggragateRootIds +{ + internal sealed class AggrageteRootIdSearcher + { + private readonly IEntitiesContext _context; + + private readonly RelationshipsBetweenEntityAndAggragaeRoot _relation; + + public AggrageteRootIdSearcher( + IEntitiesContext context, + RelationshipsBetweenEntityAndAggragaeRoot relation) + { + _context = context; + _relation = relation; + } + + public Guid SearchId(Entity entity) + { + if (entity.GetType().IsSubclassOf(typeof(AggregateRoot))) + { + return entity.Id; + } + + var aggrageteRoots = _context.GetAggregateRoots(); + + if (aggrageteRoots.Count() == 1) + { + return aggrageteRoots.Single().Id; + } + + var aggragateRootType = _relation[entity.GetType()]; + + var aggragateRoots = _context.GetAggregateRoots().Where(x => x.GetType() == aggragateRootType); + + foreach (var aggregateRoot in aggragateRoots) + { + var id = SearchInAggragates(entity, aggregateRoot); + + if (id is not null) + { + return id.Value; + } + } + + throw new NotFoundAggragateIdForDomainEvent(); + } + + private static Guid? SearchInAggragates(Entity entity, AggregateRoot aggregateRoot) + { + var fields = EntitiesFieldsInfo.Dictionary[aggregateRoot.GetType()]; + + foreach (var field in fields) + { + var isEntity = field.FieldType.IsSubclassOf(typeof(Entity)); + + if (isEntity) + { + var isEqual = field.GetValue(aggregateRoot).Equals(entity); + + if (isEqual) + { + return aggregateRoot.Id; + } + } + + if (field.FieldType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(field.FieldType)) + { + if (field.GetValue(aggregateRoot) is IEnumerable enumerable) + { + foreach (var en in enumerable) + { + if (en is Entity entityItem) + { + if (entityItem == entity) + { + return aggregateRoot.Id; + } + + } + } + } + } + } + return null; + } + } +} diff --git a/source/EasyWay/Internals/DomainEvents/AggragateRootIds/EntityStructureInDomain.cs b/source/EasyWay/Internals/DomainEvents/AggragateRootIds/EntityStructureInDomain.cs new file mode 100644 index 0000000..9c24928 --- /dev/null +++ b/source/EasyWay/Internals/DomainEvents/AggragateRootIds/EntityStructureInDomain.cs @@ -0,0 +1,45 @@ +using EasyWay.Internals.Assemblies; +using System.Collections; +using System.Reflection; + +namespace EasyWay.Internals.DomainEvents.AggragateRootIds +{ + internal static class EntityStructureInDomain + { + internal static RelationshipsBetweenEntityAndAggragaeRoot Get(IEnumerable assemblies) + { + var relation = new Dictionary(); + + var types = assemblies.SelectMany(x => x.GetTypes()); + + var aggregateRoots = types.Where(x => x.IsSubclassOf(typeof(AggregateRoot))); + + + foreach (var aggregateType in aggregateRoots) + { + var fields = EntitiesFieldsInfo.Dictionary[aggregateType]; + + foreach (var field in fields) + { + var fieldType = field.FieldType; + + var isEntity = fieldType.IsSubclassOf(typeof(Entity)); + + if (isEntity) + { + relation.Add(fieldType, aggregateType); + } + + if (fieldType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(fieldType)) + { + relation.Add(fieldType, aggregateType); + + //TODO UseCase (very rarely) entity in entity + } + } + } + + return new RelationshipsBetweenEntityAndAggragaeRoot(relation); + } + } +} diff --git a/source/EasyWay/Internals/DomainEvents/AggragateRootIds/NotFoundAggragateIdForDomainEvent.cs b/source/EasyWay/Internals/DomainEvents/AggragateRootIds/NotFoundAggragateIdForDomainEvent.cs new file mode 100644 index 0000000..6007278 --- /dev/null +++ b/source/EasyWay/Internals/DomainEvents/AggragateRootIds/NotFoundAggragateIdForDomainEvent.cs @@ -0,0 +1,7 @@ +namespace EasyWay.Internals.DomainEvents.AggragateRootIds +{ + internal sealed class NotFoundAggragateIdForDomainEvent : EasyWayException + { + internal NotFoundAggragateIdForDomainEvent() : base() { } + } +} diff --git a/source/EasyWay/Internals/DomainEvents/AggragateRootIds/RelationshipsBetweenEntityAndAggragaeRoot.cs b/source/EasyWay/Internals/DomainEvents/AggragateRootIds/RelationshipsBetweenEntityAndAggragaeRoot.cs new file mode 100644 index 0000000..549e983 --- /dev/null +++ b/source/EasyWay/Internals/DomainEvents/AggragateRootIds/RelationshipsBetweenEntityAndAggragaeRoot.cs @@ -0,0 +1,10 @@ +using System.Collections.ObjectModel; + +namespace EasyWay.Internals.DomainEvents.AggragateRootIds +{ + internal sealed class RelationshipsBetweenEntityAndAggragaeRoot : ReadOnlyDictionary + { + public RelationshipsBetweenEntityAndAggragaeRoot(IDictionary dictionary) + : base(dictionary) { } + } +} diff --git a/source/EasyWay/Internals/DomainEvents/DomainEventContext.cs b/source/EasyWay/Internals/DomainEvents/DomainEventContext.cs index b04f1d2..86023e2 100644 --- a/source/EasyWay/Internals/DomainEvents/DomainEventContext.cs +++ b/source/EasyWay/Internals/DomainEvents/DomainEventContext.cs @@ -4,9 +4,7 @@ internal sealed class DomainEventContext { internal required Guid EventId { get; init; } - internal required Guid AggragetRootId { get; init; } - - internal required Guid EntityId { get; init; } + internal required Entity Entity { get; init; } internal required DateTime OccurrenceOnUtc { get; init; } diff --git a/source/EasyWay/Internals/DomainEvents/DomainEventContextDispacher.cs b/source/EasyWay/Internals/DomainEvents/DomainEventContextDispacher.cs index 6a06f48..f3e1c93 100644 --- a/source/EasyWay/Internals/DomainEvents/DomainEventContextDispacher.cs +++ b/source/EasyWay/Internals/DomainEvents/DomainEventContextDispacher.cs @@ -4,11 +4,11 @@ internal sealed class DomainEventContextDispacher : IDomainEventContextDispacher { private readonly IDomainEventBulkPublisher _publisher; - private readonly IDomainEventsContext _context; + private readonly IDomainEventsAccessor _context; public DomainEventContextDispacher( IDomainEventBulkPublisher publisher, - IDomainEventsContext context) + IDomainEventsAccessor context) { _publisher = publisher; _context = context; diff --git a/source/EasyWay/Internals/DomainEvents/DomainEventPublisher.cs b/source/EasyWay/Internals/DomainEvents/DomainEventPublisher.cs index 0ce9f7d..f444f13 100644 --- a/source/EasyWay/Internals/DomainEvents/DomainEventPublisher.cs +++ b/source/EasyWay/Internals/DomainEvents/DomainEventPublisher.cs @@ -1,4 +1,5 @@ using EasyWay.Events.DomainEvents; +using EasyWay.Internals.DomainEvents.AggragateRootIds; using Microsoft.Extensions.DependencyInjection; namespace EasyWay.Internals.DomainEvents @@ -7,9 +8,14 @@ internal sealed class DomainEventPublisher : IDomainEventPublisher { private readonly IServiceProvider _serviceProvider; - public DomainEventPublisher(IServiceProvider serviceProvider) + private readonly AggrageteRootIdSearcher _aggrageteRootIdSearcher; + + public DomainEventPublisher( + IServiceProvider serviceProvider, + AggrageteRootIdSearcher aggrageteRootIdSearcher) { _serviceProvider = serviceProvider; + _aggrageteRootIdSearcher = aggrageteRootIdSearcher; } public async Task Publish(DomainEventContext domainEventContext) @@ -21,9 +27,9 @@ public async Task Publish(DomainEventContext domainEventContext) var eventHandlers = _serviceProvider.GetServices(handlerType); var context = new Context( - eventId: domainEventContext.EntityId, - aggragetRootId: domainEventContext.AggragetRootId, - entityId: domainEventContext.EntityId, + eventId: domainEventContext.EventId, + aggragetRootId: _aggrageteRootIdSearcher.SearchId(domainEventContext.Entity), + entityId: domainEventContext.Entity.Id, occurrenceOnUtc: domainEventContext.OccurrenceOnUtc); foreach (var eventHandler in eventHandlers) diff --git a/source/EasyWay/Internals/DomainEvents/DomainEventsAccessor.cs b/source/EasyWay/Internals/DomainEvents/DomainEventsAccessor.cs new file mode 100644 index 0000000..820379c --- /dev/null +++ b/source/EasyWay/Internals/DomainEvents/DomainEventsAccessor.cs @@ -0,0 +1,32 @@ +namespace EasyWay.Internals.DomainEvents +{ + internal sealed class DomainEventsAccessor : IDomainEventsAccessor + { + private readonly IEntitiesContext _context; + + public DomainEventsAccessor(IEntitiesContext context) => _context = context; + + public IReadOnlyCollection GetAllDomainEvents() + { + var domainEntities = _context + .GetEntities() + .Where(x => x.DomainEvents != null && x.DomainEvents.Any()) + .ToList(); + + + return domainEntities + .SelectMany(x => x.DomainEvents) + .ToList(); + } + + public void ClearAllDomainEvents() + { + var domainEntities = _context + .GetEntities() + .Where(x => x.DomainEvents != null && x.DomainEvents.Any()).ToList(); + + domainEntities + .ForEach(entity => entity.ClearDomainEvents()); + } + } +} diff --git a/source/EasyWay/Internals/DomainEvents/Extensions.cs b/source/EasyWay/Internals/DomainEvents/Extensions.cs index 95defe3..8ae621a 100644 --- a/source/EasyWay/Internals/DomainEvents/Extensions.cs +++ b/source/EasyWay/Internals/DomainEvents/Extensions.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection; +using EasyWay.Internals.DomainEvents.AggragateRootIds; +using Microsoft.Extensions.DependencyInjection; using System.Reflection; namespace EasyWay.Internals.DomainEvents @@ -11,8 +12,16 @@ internal static IServiceCollection AddDomainEvents(this IServiceCollection servi services.AddScoped(); services.AddScoped(); + services.AddScoped(); + + services.AddScoped(); + services.AddAsBasedType(typeof(DomainEventHandler<>), ServiceLifetime.Scoped, assemblies); + RelationshipsBetweenEntityAndAggragaeRoot relation = EntityStructureInDomain.Get(assemblies); + + services.AddSingleton(relation); + return services; } } diff --git a/source/EasyWay/Internals/DomainEvents/IDomainEventsContext.cs b/source/EasyWay/Internals/DomainEvents/IDomainEventsAccessor.cs similarity index 78% rename from source/EasyWay/Internals/DomainEvents/IDomainEventsContext.cs rename to source/EasyWay/Internals/DomainEvents/IDomainEventsAccessor.cs index b22c03b..56a4971 100644 --- a/source/EasyWay/Internals/DomainEvents/IDomainEventsContext.cs +++ b/source/EasyWay/Internals/DomainEvents/IDomainEventsAccessor.cs @@ -1,6 +1,6 @@ namespace EasyWay.Internals.DomainEvents { - internal interface IDomainEventsContext + internal interface IDomainEventsAccessor { IReadOnlyCollection GetAllDomainEvents(); diff --git a/source/EasyWay/Internals/DomainEvents/IEntitiesContext.cs b/source/EasyWay/Internals/DomainEvents/IEntitiesContext.cs new file mode 100644 index 0000000..37eb9c0 --- /dev/null +++ b/source/EasyWay/Internals/DomainEvents/IEntitiesContext.cs @@ -0,0 +1,9 @@ +namespace EasyWay.Internals.DomainEvents +{ + internal interface IEntitiesContext + { + IEnumerable GetAggregateRoots(); + + IEnumerable GetEntities(); + } +} diff --git a/source/EasyWay/Internals/Extensions.cs b/source/EasyWay/Internals/Extensions.cs index 34ad898..7365599 100644 --- a/source/EasyWay/Internals/Extensions.cs +++ b/source/EasyWay/Internals/Extensions.cs @@ -1,4 +1,5 @@ using EasyWay.Internals.AggregateRoots; +using EasyWay.Internals.Assemblies; using EasyWay.Internals.Clocks; using EasyWay.Internals.Commands; using EasyWay.Internals.Contexts; @@ -23,6 +24,7 @@ internal static void AddEasyWay( IEnumerable assemblies) { services + .AddAssemblies(assemblies) .AddClocks() .AddContexts() .AddLoggers(moduleType)