My current application structure is:
Data.IRepository<>
to ORM.GenericRepository<>
IRepository<>
This structure has essentially decoupled the Business layer from the ORM implementing the IRepository<T>
.
One of the benefits of this decoupled structure is that I should be able to replace the ORM relatively easily - for example, move from Entity Framework to NHibernate or just upgrading an existing ORM. I'm currently using EF 4.1 code first and am building another assembly for NHibernate.
I'm considering implementing the Unit of Work pattern.
I've read that this pattern should be used in the business layer (with interfaces defined in my Data assembly, and implemented in the ORM assembly just like I did with the repository pattern). Currently, all instantiated repositories have their own DbContext / session and its lifetime is set to that of the repository - which may be bad- my problem is that I'm not sure if its possible to implement a Unit of Work pattern that would work with different ORM's (er rather, it probably is and I'm just not up to speed).
This is the only thing that comes to mind:
Create IUnitOfWork in my Data assembly that has a function: object GetCurrentSession();
, then have an argument in the constructor of the repositorys in the ORM assembly and cast it to the appropriate session / DbContext (If NHibernate then ISession, if Entity Framework then DbContext)
I would appreciate if anyone has some insight into this situation.
Recently I made my research project where I implemented a simple ASP.NET Core CRUD API using unit of work and repository patterns. I made it so that my API controller works with persistent storage only via IUnitOfWork
abstraction. And I have separate projects for Dapper, Entity Framework Core and NHibernate, each of them implements IUnitOfWork
for specific ORM.
Here's the project link: https://github.com/pkirilin/UnitOfWorkExample
Here's a simple example:
class SomeService
{
private readonly IAppUnitOfWork _unitOfWork;
// IAppUnitOfWork is inherited from base IUnitOfWork and added to DI container
public SomeService(IAppUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public async Task DoSomethingAsync(CancellationToken cancellationToken)
{
var entity = await _unitOfWork.WeatherForecasts.GetByIdAsync(..., cancellationToken);
_unitOfWork.WeatherForecasts.Delete(entity);
var newEntity = new WeatherForecast(...);
_unitOfWork.WeatherForecasts.Add(newEntity);
await _unitOfWork.SaveChangesAsync(cancellationToken);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With