I am still learning UnitOfWork pattern and I am not comfortable with this yet. I found many examples but nothing is clear enough for my problem. I want use UnitOfWork with Ado.Net. I have many repositories. I want call different methods from different repositories in same transaction using Unit of work.
For example a have this 2 repositories.
public class FirstRepository : IFirstRepository
{
private readonly ILogger logger;
private readonly IImportConfiguration configuration;
public FirstRepository(ILogger logger, IImportConfiguration configuration)
{
this.logger = logger;
this.configuration = configuration;
}
public int Save()
{
//Save to DB with Ado.Net
return 1;
}
}
public class SecondRepository : ISecondRepository
{
private readonly ILogger logger;
private readonly IImportConfiguration configuration;
public SecondRepository(ILogger logger, IImportConfiguration configuration)
{
this.logger = logger;
this.configuration = configuration;
}
public int Update()
{
//Update in DB with Ado.Net
return 1;
}
}
I want call functions Save() and Update() in same transaction.
using (var uow = UnitOfWorkFactory.Create())
{
firstRepository.Save();
secondRepository.Update();
_unitOfWork.SaveChanges();
}
Problem is how to use same UnitOfWork in both repositories ? Only thing I can see is add additional parameter to functions
//in first repository
Save(IUnitOfWork uow)
//in second repository
Update(IUnitOfWork uow)
//****************************
using (var uow = UnitOfWorkFactory.Create())
{
firstRepository.Save(uow);
secondRepository.Update(uow);
_unitOfWork.SaveChanges();
}
This is ugly solution, because i must have this parameter in all functions that work with DB. I am using Dependency injection. ILogger and IImportConfiguration are injected with AutoFac. Maybe would be good to register all repositories in UnitOfWork? But how to do that? I cant have just one instance injected in all repositories. Any idea?
Tying it all together:
So to use DI, you need to create interfaces for all these.
The unit of work is based round some Data Layer connection, for example EF uses
DbContext
which you would use in the underlyingUnitOfWork
class.Other things you can do is make
IUnitOfWork
(the interface) inheritIDisposable
so you use theusing()
.To make it so you don't have a hundred repository classes (although not really a bad thing) you can make it Generic, so
IRepository<T>
andRepository<T>
So for a generic repo and unit of work using EF.
Usage: