Maik
Maik
CC#
Created by Maik on 6/7/2024 in #help
Resolving correct DbContext depending on ???
Hey everyone, I'm building a modular application with ASP.NET 8 and using the inbox/outbox pattern for communication between modules. Scenario: - Module A receives an integration event. - I want to store this event in the database using a generic IInboxRepository. - Challenge: Each module has its own DbContext for its specific data. How can I design my IInboxRepository to resolve the correct DbContext and save the integration event in the appropriate inbox table for the originating module? Right now I am thinking about something like this, but I don't like it to be honest. I don't know why lol
public interface IDbContext
{
DbSet<TEntity> Set<TEntity>() where TEntity : class;

Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
}

public interface IInboxRepository<T>
where T : IDbContext
{
Task AddAndSaveAsync(IIntegrationEvent integrationEvent, CancellationToken cancellationToken = default);
}

public sealed class GenericIntegrationEventHandler<TEvent, TDbContext>(
IInboxRepository<TDbContext> inboxRepository)
: IIntegrationEventHandler<TEvent>
where TEvent : class, IIntegrationEvent
where TDbContext : IDbContext
{
private readonly IInboxRepository<TDbContext> _inboxRepository = inboxRepository;

public async Task Handle(TEvent notification, CancellationToken cancellationToken)
{
await _inboxRepository.AddAndSaveAsync(notification, cancellationToken);
}
}

public sealed class InboxRepository<T>(T dbContext)
: IInboxRepository<T>
where T : IDbContext
{
private readonly T _dbContext = dbContext;

public async Task AddAndSaveAsync(IIntegrationEvent integrationEvent, CancellationToken cancellationToken = default)
{
// Do stuff here
}
}
public interface IDbContext
{
DbSet<TEntity> Set<TEntity>() where TEntity : class;

Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
}

public interface IInboxRepository<T>
where T : IDbContext
{
Task AddAndSaveAsync(IIntegrationEvent integrationEvent, CancellationToken cancellationToken = default);
}

public sealed class GenericIntegrationEventHandler<TEvent, TDbContext>(
IInboxRepository<TDbContext> inboxRepository)
: IIntegrationEventHandler<TEvent>
where TEvent : class, IIntegrationEvent
where TDbContext : IDbContext
{
private readonly IInboxRepository<TDbContext> _inboxRepository = inboxRepository;

public async Task Handle(TEvent notification, CancellationToken cancellationToken)
{
await _inboxRepository.AddAndSaveAsync(notification, cancellationToken);
}
}

public sealed class InboxRepository<T>(T dbContext)
: IInboxRepository<T>
where T : IDbContext
{
private readonly T _dbContext = dbContext;

public async Task AddAndSaveAsync(IIntegrationEvent integrationEvent, CancellationToken cancellationToken = default)
{
// Do stuff here
}
}
Does anybody know how I could design this better? Or maybe someone has a complete different approach? I highly appreciate any kind of help
3 replies