From 7758dbe33750eb6379d00443b4ef437e1fd89153 Mon Sep 17 00:00:00 2001 From: David Eggenberger Date: Sun, 27 Oct 2024 21:27:15 +0100 Subject: [PATCH] removed AggregateRoot base object --- .../StripeSubscription.cs | 2 +- .../Application/Commands/AddUserToTenant.cs | 2 +- .../TenantAggregate/Domain/Tenant.cs | 2 +- .../Shared/Features/Domain/AggregateRoot.cs | 23 ------------------- Source/Shared/Features/Domain/Entity.cs | 19 +++++++++++++-- .../Shared/Features/EFCore/BaseDbContext.cs | 11 +-------- .../Shared/Features/EFCore/DbSetExtensions.cs | 4 ++-- .../EFCore/ExecutionContextInterceptor.cs | 4 ++-- .../MultiTenancyEntityConfiguration.cs | 23 ++++--------------- Source/Shared/Kernel/Interfaces/IAuditable.cs | 1 - 10 files changed, 29 insertions(+), 62 deletions(-) delete mode 100644 Source/Shared/Features/Domain/AggregateRoot.cs diff --git a/Source/Modules/Subscriptions/Features/DomainFeatures/StripeSubscriptionAggregate/StripeSubscription.cs b/Source/Modules/Subscriptions/Features/DomainFeatures/StripeSubscriptionAggregate/StripeSubscription.cs index d85c20bd..ef60e9fc 100644 --- a/Source/Modules/Subscriptions/Features/DomainFeatures/StripeSubscriptionAggregate/StripeSubscription.cs +++ b/Source/Modules/Subscriptions/Features/DomainFeatures/StripeSubscriptionAggregate/StripeSubscription.cs @@ -4,7 +4,7 @@ namespace Modules.Subscriptions.Features.DomainFeatures.StripeSubscriptionAggregate { - public class StripeSubscription : AggregateRoot + public class StripeSubscription : Entity { private StripeSubscription() { } diff --git a/Source/Modules/TenantIdentity/Features/DomainFeatures/TenantAggregate/Application/Commands/AddUserToTenant.cs b/Source/Modules/TenantIdentity/Features/DomainFeatures/TenantAggregate/Application/Commands/AddUserToTenant.cs index 642e1a0a..b965a476 100644 --- a/Source/Modules/TenantIdentity/Features/DomainFeatures/TenantAggregate/Application/Commands/AddUserToTenant.cs +++ b/Source/Modules/TenantIdentity/Features/DomainFeatures/TenantAggregate/Application/Commands/AddUserToTenant.cs @@ -18,7 +18,7 @@ public AddUserToTenantCommandHandler(IServiceProvider serviceProvider) : base(se public async Task HandleAsync(AddUserToTenant command, CancellationToken cancellationToken) { - var tenant = await module.TenantIdentityDbContext.Tenants.GetAggregateRootAsync(command.TenantId, command.TenantId); + var tenant = await module.TenantIdentityDbContext.Tenants.GetEntityAsync(command.TenantId, command.TenantId); tenant.AddUser(command.UserId, command.Role); diff --git a/Source/Modules/TenantIdentity/Features/DomainFeatures/TenantAggregate/Domain/Tenant.cs b/Source/Modules/TenantIdentity/Features/DomainFeatures/TenantAggregate/Domain/Tenant.cs index 8d3c76cb..389a394a 100644 --- a/Source/Modules/TenantIdentity/Features/DomainFeatures/TenantAggregate/Domain/Tenant.cs +++ b/Source/Modules/TenantIdentity/Features/DomainFeatures/TenantAggregate/Domain/Tenant.cs @@ -6,7 +6,7 @@ namespace Modules.TenantIdentity.Features.DomainFeatures.TenantAggregate.Domain { - public class Tenant : AggregateRoot + public class Tenant : Entity { public Tenant() { } diff --git a/Source/Shared/Features/Domain/AggregateRoot.cs b/Source/Shared/Features/Domain/AggregateRoot.cs deleted file mode 100644 index bd92f307..00000000 --- a/Source/Shared/Features/Domain/AggregateRoot.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Shared.Kernel.BuildingBlocks; -using Shared.Kernel.BuildingBlocks.Auth; -using Shared.Kernel.BuildingBlocks.Auth.Exceptions; -using Shared.Kernel.Interfaces; -using System.ComponentModel.DataAnnotations.Schema; - -namespace Shared.Features.Domain -{ - public class AggregateRoot : Entity, ITenantIdentifiable - { - [NotMapped] - public IExecutionContext ExecutionContext { get; set; } - public virtual Guid TenantId { get; set; } - - public void ThrowIfCallerIsNotInRole(TenantRole role) - { - if (ExecutionContext.TenantRole != role) - { - throw new UnauthorizedException(); - } - } - } -} diff --git a/Source/Shared/Features/Domain/Entity.cs b/Source/Shared/Features/Domain/Entity.cs index bdbcc6e3..a5b545c2 100644 --- a/Source/Shared/Features/Domain/Entity.cs +++ b/Source/Shared/Features/Domain/Entity.cs @@ -1,5 +1,9 @@ -using Shared.Kernel.Interfaces; +using Shared.Kernel.BuildingBlocks.Auth; +using Shared.Kernel.BuildingBlocks; +using Shared.Kernel.Interfaces; using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Shared.Kernel.BuildingBlocks.Auth.Exceptions; namespace Shared.Features.Domain { @@ -8,7 +12,7 @@ public abstract class Entity : IAuditable, IIdentifiable, IConcurrent [Key] public Guid Id { get; set; } - public Guid CreatedByUserId { get; set; } + public virtual Guid TenantId { get; set; } [ConcurrencyCheck] public byte[] RowVersion { get; set; } @@ -16,5 +20,16 @@ public abstract class Entity : IAuditable, IIdentifiable, IConcurrent public DateTimeOffset CreatedAt { get; set; } public DateTimeOffset LastUpdatedAt { get; set; } + + [NotMapped] + public IExecutionContext ExecutionContext { get; set; } + + public void ThrowIfCallerIsNotInRole(TenantRole role) + { + if (ExecutionContext.TenantRole != role) + { + throw new UnauthorizedException(); + } + } } } diff --git a/Source/Shared/Features/EFCore/BaseDbContext.cs b/Source/Shared/Features/EFCore/BaseDbContext.cs index 08f1c755..28a713eb 100644 --- a/Source/Shared/Features/EFCore/BaseDbContext.cs +++ b/Source/Shared/Features/EFCore/BaseDbContext.cs @@ -54,7 +54,6 @@ public override async Task SaveChangesAsync(CancellationToken cancellationT ThrowIfMultipleTenants(); UpdateAutitableEntities(); SetTenantId(); - UpdateCreatedByUserEntities(executionContext.UserId); return await base.SaveChangesAsync(cancellationToken); } @@ -75,14 +74,6 @@ private void UpdateAutitableEntities() } } - private void UpdateCreatedByUserEntities(Guid userId) - { - foreach (var entry in ChangeTracker.Entries().Where(x => x.State == EntityState.Added)) - { - entry.Entity.CreatedByUserId = userId; - } - } - private void SetTenantId() { foreach (var entry in ChangeTracker.Entries().Where(x => x.State == EntityState.Added)) @@ -117,7 +108,7 @@ private void ThrowIfMultipleTenants() private void ThrowIfDbSetEntityNotTenantIdentifiable(ModelBuilder modelBuilder) { - foreach (var entityType in modelBuilder.Model.GetEntityTypes().Where(t => t is AggregateRoot)) + foreach (var entityType in modelBuilder.Model.GetEntityTypes().Where(t => t is Entity)) { if (typeof(ITenantIdentifiable).IsAssignableFrom(entityType.ClrType) is false) { diff --git a/Source/Shared/Features/EFCore/DbSetExtensions.cs b/Source/Shared/Features/EFCore/DbSetExtensions.cs index fe41c4ec..40aeed01 100644 --- a/Source/Shared/Features/EFCore/DbSetExtensions.cs +++ b/Source/Shared/Features/EFCore/DbSetExtensions.cs @@ -5,9 +5,9 @@ namespace Shared.Features.EFCore { public static class DbSetExtensions { - public static async Task GetAggregateRootAsync(this DbSet dbSet, Guid owningTenantId, Guid aggregateRootId) where TAggregateRoot : AggregateRoot + public static async Task GetEntityAsync(this DbSet dbSet, Guid owningTenantId, Guid entityId) where TEntity : Entity { - return await dbSet.FirstAsync(t => t.TenantId == owningTenantId && t.Id == aggregateRootId); + return await dbSet.FirstAsync(t => t.TenantId == owningTenantId && t.Id == entityId); } } } diff --git a/Source/Shared/Features/EFCore/ExecutionContextInterceptor.cs b/Source/Shared/Features/EFCore/ExecutionContextInterceptor.cs index 538fc2e4..5a8adbfb 100644 --- a/Source/Shared/Features/EFCore/ExecutionContextInterceptor.cs +++ b/Source/Shared/Features/EFCore/ExecutionContextInterceptor.cs @@ -11,9 +11,9 @@ public object InitializedInstance( MaterializationInterceptionData materializationData, object instance) { - if (instance is AggregateRoot aggregateRoot) + if (instance is Entity entity) { - aggregateRoot.ExecutionContext = materializationData + entity.ExecutionContext = materializationData .Context .GetService(); } diff --git a/Source/Shared/Features/EFCore/MultiTenancy/MultiTenancyEntityConfiguration.cs b/Source/Shared/Features/EFCore/MultiTenancy/MultiTenancyEntityConfiguration.cs index 15259885..076e5226 100644 --- a/Source/Shared/Features/EFCore/MultiTenancy/MultiTenancyEntityConfiguration.cs +++ b/Source/Shared/Features/EFCore/MultiTenancy/MultiTenancyEntityConfiguration.cs @@ -6,40 +6,25 @@ namespace Shared.Features.EFCore.MultiTenancy { public static class MultiTenancyEntityConfiguration { - static void ConfigureAggregateRoot(ModelBuilder modelBuilder, Guid teamId) - where TAggregateRoot : AggregateRoot - { - modelBuilder.Entity(builder => - { - builder.HasQueryFilter(x => x.TenantId == teamId); - }); - } - - static void ConfigureEntity(ModelBuilder modelBuilder) + static void ConfigureEntity(ModelBuilder modelBuilder, Guid tenantId) where TEntity : Entity { modelBuilder.Entity(builder => { builder.HasKey(x => x.Id); builder.Property(e => e.RowVersion).IsConcurrencyToken(); + builder.HasQueryFilter(x => x.TenantId == tenantId); }); } - public static ModelBuilder ApplyBaseEntityConfiguration(this ModelBuilder modelBuilder, Guid teamId) + public static ModelBuilder ApplyBaseEntityConfiguration(this ModelBuilder modelBuilder, Guid tenantId) { - var configureAggregateRootMethod = typeof(MultiTenancyEntityConfiguration).GetTypeInfo().DeclaredMethods - .Single(m => m.Name == nameof(ConfigureAggregateRoot)); var configureEntityMethod = typeof(MultiTenancyEntityConfiguration).GetTypeInfo().DeclaredMethods .Single(m => m.Name == nameof(ConfigureEntity)); - - foreach (var entityType in modelBuilder.Model.GetEntityTypes().Where(x => x is AggregateRoot)) - { - configureAggregateRootMethod.MakeGenericMethod(entityType.ClrType, entityType.GetType()).Invoke(null, new object[] { modelBuilder, teamId }); - } foreach (var entityType in modelBuilder.Model.GetEntityTypes().Where(x => x is Entity)) { - configureEntityMethod.MakeGenericMethod(entityType.ClrType, entityType.GetType()).Invoke(null, new object[] { modelBuilder }); + configureEntityMethod.MakeGenericMethod(entityType.ClrType, entityType.GetType()).Invoke(null, new object[] { modelBuilder, tenantId }); } return modelBuilder; diff --git a/Source/Shared/Kernel/Interfaces/IAuditable.cs b/Source/Shared/Kernel/Interfaces/IAuditable.cs index bbd45e84..dca31c48 100644 --- a/Source/Shared/Kernel/Interfaces/IAuditable.cs +++ b/Source/Shared/Kernel/Interfaces/IAuditable.cs @@ -2,7 +2,6 @@ { public interface IAuditable { - Guid CreatedByUserId { get; set; } DateTimeOffset CreatedAt { get; set; } DateTimeOffset LastUpdatedAt { get; set; } }