femto-backend/Femto.Modules.Auth/Data/AuthContext.cs
2025-06-16 21:11:40 +02:00

63 lines
No EOL
2.1 KiB
C#

using Femto.Common.Domain;
using Femto.Common.Infrastructure.Outbox;
using Femto.Modules.Auth.Models;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.Logging;
namespace Femto.Modules.Auth.Data;
internal class AuthContext(DbContextOptions<AuthContext> options) : DbContext(options), IOutboxContext
{
public virtual DbSet<UserIdentity> Users { get; set; }
public virtual DbSet<SignupCode> SignupCodes { get; set; }
public virtual DbSet<LongTermSession> LongTermSessions { get; set; }
public virtual DbSet<OutboxEntry> Outbox { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.HasDefaultSchema("authn");
builder.ApplyConfigurationsFromAssembly(typeof(AuthContext).Assembly);
}
public override int SaveChanges()
{
throw new InvalidOperationException("Use SaveChangesAsync instead");
}
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
await EmitDomainEvents(cancellationToken);
return await base.SaveChangesAsync(cancellationToken);
}
private async Task EmitDomainEvents(CancellationToken cancellationToken)
{
var logger = this.GetService<ILogger<AuthContext>>();
var publisher = this.GetService<IPublisher>();
var domainEvents = this
.ChangeTracker.Entries<Entity>()
.SelectMany(e =>
{
var events = e.Entity.DomainEvents;
e.Entity.ClearDomainEvents();
return events;
})
.ToList();
logger.LogTrace("loaded {Count} domain events", domainEvents.Count);
foreach (var domainEvent in domainEvents)
{
logger.LogTrace(
"publishing {Type} domain event {Id}",
domainEvent.GetType().Name,
domainEvent.EventId
);
await publisher.Publish(domainEvent, cancellationToken);
}
}
}