C
C#6mo 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
Pobiega6mo 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
Want results from more Discord servers?
Add your server