Skip to content

Commit

Permalink
removed AggregateRoot base object
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidEggenberger committed Oct 27, 2024
1 parent 7f45343 commit 7758dbe
Show file tree
Hide file tree
Showing 10 changed files with 29 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Modules.Subscriptions.Features.DomainFeatures.StripeSubscriptionAggregate
{
public class StripeSubscription : AggregateRoot
public class StripeSubscription : Entity
{
private StripeSubscription() { }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

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

namespace Modules.TenantIdentity.Features.DomainFeatures.TenantAggregate.Domain
{
public class Tenant : AggregateRoot
public class Tenant : Entity
{
public Tenant() { }

Expand Down
23 changes: 0 additions & 23 deletions Source/Shared/Features/Domain/AggregateRoot.cs

This file was deleted.

19 changes: 17 additions & 2 deletions Source/Shared/Features/Domain/Entity.cs
Original file line number Diff line number Diff line change
@@ -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
{
Expand All @@ -8,13 +12,24 @@ 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; }

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();
}
}
}
}
11 changes: 1 addition & 10 deletions Source/Shared/Features/EFCore/BaseDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ public override async Task<int> SaveChangesAsync(CancellationToken cancellationT
ThrowIfMultipleTenants();
UpdateAutitableEntities();
SetTenantId();
UpdateCreatedByUserEntities(executionContext.UserId);
return await base.SaveChangesAsync(cancellationToken);
}

Expand All @@ -75,14 +74,6 @@ private void UpdateAutitableEntities()
}
}

private void UpdateCreatedByUserEntities(Guid userId)
{
foreach (var entry in ChangeTracker.Entries<IAuditable>().Where(x => x.State == EntityState.Added))
{
entry.Entity.CreatedByUserId = userId;
}
}

private void SetTenantId()
{
foreach (var entry in ChangeTracker.Entries<ITenantIdentifiable>().Where(x => x.State == EntityState.Added))
Expand Down Expand Up @@ -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)
{
Expand Down
4 changes: 2 additions & 2 deletions Source/Shared/Features/EFCore/DbSetExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ namespace Shared.Features.EFCore
{
public static class DbSetExtensions
{
public static async Task<TAggregateRoot> GetAggregateRootAsync<TAggregateRoot>(this DbSet<TAggregateRoot> dbSet, Guid owningTenantId, Guid aggregateRootId) where TAggregateRoot : AggregateRoot
public static async Task<TEntity> GetEntityAsync<TEntity>(this DbSet<TEntity> 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);
}
}
}
4 changes: 2 additions & 2 deletions Source/Shared/Features/EFCore/ExecutionContextInterceptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<IExecutionContext>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,25 @@ namespace Shared.Features.EFCore.MultiTenancy
{
public static class MultiTenancyEntityConfiguration
{
static void ConfigureAggregateRoot<TAggregateRoot>(ModelBuilder modelBuilder, Guid teamId)
where TAggregateRoot : AggregateRoot
{
modelBuilder.Entity<TAggregateRoot>(builder =>
{
builder.HasQueryFilter(x => x.TenantId == teamId);
});
}

static void ConfigureEntity<TEntity, T>(ModelBuilder modelBuilder)
static void ConfigureEntity<TEntity, T>(ModelBuilder modelBuilder, Guid tenantId)
where TEntity : Entity
{
modelBuilder.Entity<TEntity>(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;
Expand Down
1 change: 0 additions & 1 deletion Source/Shared/Kernel/Interfaces/IAuditable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
{
public interface IAuditable
{
Guid CreatedByUserId { get; set; }
DateTimeOffset CreatedAt { get; set; }
DateTimeOffset LastUpdatedAt { get; set; }
}
Expand Down

0 comments on commit 7758dbe

Please sign in to comment.