Reputation: 10374
In many basic examples I see the using block wrapped around DbContext
usage like so:
using (var context = new MyDbContext())
{
// Perform data access using the context
}
It makes sense, because a 'new' instance is being created, so you want to dispose of this once you are finished with it.
Using DI
However in a number of projects I am working with, I am seeing DbContext
being injected into repositories and service layers like this:
public class FileRequestService : IFileRequestService
{
private readonly MyDbContext _myDbContext;
public FileRequestService(MyDbContext myDbContext)
{
_myDbContext = myDbContext;
}
public FileRequest SaveFileRequest(FileRequest fileRequest)
{
fileRequest.Status = FileRequestStatus.New;
//...
//...
var fr = _myDbContext.FileRequests.Add(fileRequest);
_myDbContext.SaveChanges();
return fr;
}
}
And configured in the DI container like this:
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
container.Register<MyDbContext>(Lifestyle.Singleton);
Question 1
Is it OK that there is no using statement being used here, as it is presumably being disposed of once the web request dies?
Using DI/UoW
Similar scenario for the unit of work pattern, I am seeing this:
public class RecordController : Controller
{
private readonly IUnitOfWork _unitOfWork;
public RecordController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
[HttpPost, ActionName("Index")]
public PartialViewResult Search(SearchQueryViewModel searchQueryViewModel)
{
var deptId =
_unitOfWork.DepartmentRepository.Get(x => x.DepartmentCode == searchQueryViewModel.code)
.Select(s => s.DepartmentId)
.FirstOrDefault();
//...
}
}
Which is configured in the container like so:
container.Register<IUnitOfWork, UnitOfWork>(Lifestyle.Scoped);
container.Register<IGenericRepository<Department>, GenericRepository<Department>>(Lifestyle.Scoped);
And DbContext
is being injected into the constructor of the UoW class as normal.
Question 2
Again is it OK that there is no using statement being used here or should I implement the IDisposable
interface on the UoW class and do something like this:
using (_unitOfWork)
{
var deptId =
_unitOfWork.DepartmentRepository.Get(x => x.DepartmentCode == searchQueryViewModel.code)
.Select(s => s.DepartmentId)
.FirstOrDefault();
//...
}
Upvotes: 2
Views: 159
Reputation: 170
Simply put, whoever creates an instance should be the one responsible for calling its dispose method.
On Question 1: I would personally avoid the use of singletons for the DbContext. A quick search on google shows many articles/Stackoverflow questions but here is the first one in line : Entity Framework Context in Singleton In your current case - it will not get disposed, never. It is registered in a singleton scope which means you would have a single instance that will kept as long as the container is. (simple injector scopes help page for reference - http://simpleinjector.readthedocs.io/en/latest/lifetimes.html )
On Question 2: Most containers would call the dispose method of all IDisposable instances once they leave their scope. If you call dispose yourself earlier, you might end up disposing the instance that is going to be provided as a dependency somewhere else. Doing so will result in the other code trying to use that very same disposed instance...
EDIT: if the scope is not controlled by the DI framework, you would have to call dispose on your own of course. But this is not the case that we are discussing
Upvotes: 2