Перепиливание под чистый DDD
This commit is contained in:
+88
@@ -0,0 +1,88 @@
|
||||
using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
using Knot.Modules.Conversations.Application.Abstractions;
|
||||
using Knot.Modules.Conversations.Domain;
|
||||
using Knot.Shared.Kernel;
|
||||
using Knot.Shared.Kernel.Security;
|
||||
|
||||
namespace Knot.Modules.Conversations.Infrastructure.Persistence;
|
||||
|
||||
/// <summary>
|
||||
/// Контекст базы данных для модуля чатов.
|
||||
/// </summary>
|
||||
public sealed class ChatsDbContext : DbContext, IChatsUnitOfWork
|
||||
{
|
||||
private readonly IMediator _mediator;
|
||||
private readonly IEncryptionService _encryptionService;
|
||||
|
||||
public ChatsDbContext(DbContextOptions<ChatsDbContext> options, IMediator mediator, IEncryptionService encryptionService)
|
||||
: base(options)
|
||||
{
|
||||
_mediator = mediator;
|
||||
_encryptionService = encryptionService;
|
||||
}
|
||||
|
||||
public DbSet<Chat> Chats => Set<Chat>();
|
||||
|
||||
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
base.OnConfiguring(optionsBuilder);
|
||||
optionsBuilder.ConfigureWarnings(w => w.Ignore(RelationalEventId.PendingModelChangesWarning));
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.HasDefaultSchema("chats");
|
||||
|
||||
modelBuilder.Entity<Chat>(builder =>
|
||||
{
|
||||
builder.ToTable("Chats");
|
||||
builder.HasKey(c => c.Id);
|
||||
builder.Property(c => c.Type).HasConversion<string>();
|
||||
|
||||
|
||||
builder.OwnsMany(c => c.Members, mb =>
|
||||
{
|
||||
mb.ToTable("ChatMembers");
|
||||
mb.HasKey(m => m.Id);
|
||||
mb.WithOwner().HasForeignKey(m => m.ChatId);
|
||||
mb.HasIndex(m => new { m.ChatId, m.UserId }).IsUnique();
|
||||
}).Navigation(c => c.Members).UsePropertyAccessMode(PropertyAccessMode.Field);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
// 1. Получаем все события из агрегатов
|
||||
var domainEvents = ChangeTracker
|
||||
.Entries<IAggregateRoot>()
|
||||
.SelectMany(x =>
|
||||
|
||||
{
|
||||
if (x.Entity is AggregateRoot<Guid> root)
|
||||
{
|
||||
var events = root.GetDomainEvents().ToList();
|
||||
root.ClearDomainEvents();
|
||||
return events;
|
||||
}
|
||||
return Enumerable.Empty<IDomainEvent>();
|
||||
})
|
||||
.ToList();
|
||||
|
||||
// 2. Сохраняем изменения
|
||||
int result = await base.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// 3. Публикуем события через MediatR
|
||||
foreach (var domainEvent in domainEvents)
|
||||
{
|
||||
await _mediator.Publish(domainEvent, cancellationToken);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user