Reputation: 465
I've run into a bit of a problem with EF looking for the best practice for this problem:
public void TestEntityFramework_UOWImplementation()
{
using (UnitOfWorkInventory uow = new UnitOfWorkInventory())
{
IMaterialRepository repos = new MaterialRepository(uow);
Material mat = GetMaterial("Mikes Material", 1);
mat.CostPrice = 20;
repos.InsertOrUpdate(mat);
uow.Commit();
}
}
private Material GetMaterial(string sku, int clientId)
{
IMaterialRepository repos = new MaterialRepository(new UnitOfWorkInventory();
return repos.Find(sku, clientId);
}
In the TestEntityFramework_UOWImplementation() method, its fine, i call create a scope for my unit of work.. and create a repository inside it.
But when i want to getMaterials() as below.. I have no access to the unit of work or the repository, unless i actually pass it as a parameter! This is clearly not particularly nice.
How do people get around this problem??
Thanks in advance!
Neil
Upvotes: 6
Views: 2977
Reputation: 465
If anyone was looking for a way around this, I done something a bit different.
I used a Dependency Injection framework (StructureMap) to handle all DI, so everytime i instantiate a repository it will retrieve the DBContext from the Service Locator of StructureMap. I also make the dbcontext scope to be for the duration of the request from the webserver.
The advantage here being that everytime i retrieve or inject a DBContext, it will retrieve the same context for the duration of the request meaning i can use this across multiple methods and class! I pass the interface type as a generic param to the constructor, meaning that i can point the repo as different contexts. Helpful in applications where there are lots of dbcontexts.
Repo Constructor Eg:
public class PurchaseOrderRepository<TDbContext> : GenericRepository<PurchaseOrder>, IPurchaseOrderRepository<TDbContext> where TDbContext : DbContext
{
public PurchaseOrderRepository()
: base((TDbContext)ObjectFactory.GetInstance<TDbContext>())
{
}
}
Usage:
//resolves the request scope InventoryContext...
var pRepos = new PurchaseOrderRepository<IInventoryContext>();
and the structure map dependency looks like:
For<IInventoryContext>().HttpContextScoped().Use<InventoryContext>();
Upvotes: 0
Reputation: 1144
In your implementation you wont have access to the Unit of Work like that. What I do is use an IoC container and Dependency Injection to handle it. I have a WCF service that uses Unit of Work with a repository pattern against EF5.
You can read more about repository pattern, unit of work, and EF here but basically what I do is in the constructor of my service class I inject the Unit of Work like so:
private readonly IUnitOfWork uow;
public LoanService(IUnitOfWork unitOfWork)
{
uow = unitOfWork;
}
Then I can use uow.WhateverMethod in my repos anywhere in the service. I use Ninject to handle the injection of IUnitOfWork. Hope it helps you.
Upvotes: 3