I'm using .NET Core 3.1. I have the following problem: I want to do a transaction in the Application layer. There I have a DbContext interface because I don't want to have access to the Infrastructure layer where I have the DbContext class. In other architectures I was able to access the Database field and therefore the Transaction because I was injecting the DbContext class. Now I'm injecting the DbContext interface I created and I don't know how to add the necessary fields that has as result the possible usage of Database field from the DbContext class. Here is the Infrastructure layer DbContext.
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, long>, IApplicationDbContext
{
private readonly ICurrentUserService _currentUserService;
private readonly IDateTime _dateTime;
public ApplicationDbContext(DbContextOptions options, ICurrentUserService currentUserService, IDateTime dateTime)
: base(options)
{
_currentUserService = currentUserService;
_dateTime = dateTime;
}
public DbSet<City> Cities { get; set; }
}
And here is the Application layer DbContext interface.
public interface IApplicationDbContext
{
Task<int> SaveChangesAsync(CancellationToken cancellationToken);
public DbSet<City> Cities { get; set; }
}
I want to be able to do something like this
public class CityService
{
private readonly IApplicationDbContext _context;
public CityService(IApplicationDbContext context)
{
_context = context;
}
public Task AddAsync(City city, CancellationToken cancellationToken)
{
using var transaction = _context.Database.BeginTransaction();
try
{
await _context.AddAsync(city, cancellationToken);
await _context.SaveChangesAsync(cancellationToken);
await transaction.CommitAsync();
}
catch (Exception e)
{
await transaction.RollbackAsync();
}
}
}
I found a solution for my problem. In the interface I added the following field:
public DatabaseFacade Database { get; }
After that I used it in the way I desired in the last code section from my question. Everything works like a charm! I don't know if it is the best way to do this but it works for me.