Reputation: 1400
I'm currently trying to introduce the Unit of Work pattern in my .NET application, in order to create a transactional behavior for MediatR:
public sealed class TransactionalBehavior<TCommand, TResponse>(
ILogger<TransactionBehavior<TCommand, TResponse>> logger,
IUnitOfWork unitOfWork)
: IBehavior<TCommand, TResponse>
where TCommand : class, ICommand<TResponse>
where TResponse : class
{
private readonly ILogger<TransactionBehavior<TCommand, TResponse>> _logger = logger;
private readonly IUnitOfWork _unitOfWork = unitOfWork;
public async Task<TResponse> Handle(
TCommand request,
RequestHandlerDelegate<TResponse> next,
CancellationToken cancellationToken)
{
using var transaction = await _unitOfWork.BeginTransactionAsync(cancellationToken);
_logger.LogInformation("Started transaction.");
try
{
var response = await next();
await transaction.CommitAsync(cancellationToken);
return response;
}
catch (Exception)
{
await transaction.RollbackAsync(cancellationToken);
throw;
}
}
}
The problem is that I got one DbContext
for each module, which all implement the IUnitOfWork
on it's own. Therefore I got multiple IUnitOfWork
's in my dependency container.
public interface IUnitOfWork
{
public Task<IDbContextTransaction> BeginTransactionAsync(CancellationToken cancellationToken = default);
public Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
}
Here is one of the DbContext
's as an example:
internal sealed class AuctionhouseDbContext(
DbContextOptions<AuctionhouseDbContext> options)
: DbContext(options),
IUnitOfWork
{
public const string Schema = "auctionhouse";
// DbSet<T>'s here...
protected override void OnModelCreating(
ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.HasDefaultSchema(Schema);
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}
public async Task<IDbContextTransaction> BeginTransactionAsync(
CancellationToken cancellationToken = default)
{
return await Database.BeginTransactionAsync(cancellationToken);
}
}
Now the question, how can I change the Unit of Work pattern, so that the MediatR behavior resolves the correct IUnitOfWork? I already thought of a generic IUnitOfWork, but I am not sure if this is the most suitable solution.
Does anybody knows how to solve my problem? Thanks in advance
Upvotes: 0
Views: 65