C
C#9mo ago
Maik

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
1 Reply
Pobiega
Pobiega9mo ago
Why use a repository over EF? DbSet I'd already a generic repository you could however have an interface shared among all your dbcontexts, something like IIntegrationContext or whatever, that each context implements differently

Did you find this page helpful?