views:

73

answers:

3

I need to inject EF context per request. Is there any way to implement it?

+1  A: 

What do you mean by injecting? Do you mean to apply dependency inversion principle on it? If yes then do you ever envisage yourself swapping out your EF context with some other context which adheres to same contract?

To me you should encapsulate EF context somewhere in framework, so that every request gets EF DataContext. Apply DI on your repository. Later on your repositories might have different kind of contexts and you can switch repositories with each other.

Pradeep
+2  A: 

Did you check out this excellent blog on DI with Unity and ASP.NET MVC?

Should get you on the right track.

The answer is yes, you can - and the article shows you how.

In short, you create a HttpContextLifetimeManager to handle the "scoping" of your objects. The container "caches" the instance in the HTTP Context.

This is needed because the default life time managers provided by Unity don't cover HTTP Context scoping "off the shelf".

Of course, other DI container's (such as StructureMap - which i use), do.

Here is another (more up to date) article on the same thing, with the "Nerdinner" as the example.

RPM1984
If you see the post that you suggested, there he is doing DI on repository as I suggested and he is encapsulating DataContext at some other place. And then within the repository method that author is getting DataContext from some central location.
Pradeep
I saw your suggestion, and i agree (i also use Repository/UoW). However, this is not a question on design patterns - it's a question on context-scoping for DI, which im hoping my answer helps with.
RPM1984
+1 - Nice suggestions and articles. I like StructureMap's built in way of HttpContext scoping and this goes about the issue the same way.
PHeiberg
Yep. This single issue is the reason why i choose StructureMap over Unity. HTTP Context scoping should be built into Unity - i have no idea why its not. Should never use singletons for db connections.
RPM1984
It's not built in due to worries about dependencies - if we put the HttpContextLifetime then the the DLL can't be used with the .NET 4.0 client profile.
Chris Tavares
Yes, that's true. Don't know how StructureMap does this then, as the "Hybrid" option is built into the StructureMap core DLL.
RPM1984
+2  A: 

The solution proposed in the Unity Discussion list is to create a child container per request, have that child container create the EF context as ContainerControlledLifetime, then have the child container disposed at the end of the request. By doing so you don't have to create a custom LifetimeManager.

I'm not very familiar with Unity but the principle would be something like this:

Application_BeginRequest(...)
{
  var childContainer = _container.CreateChildContainer();
  HttpContext.Items["container"] = childContainer;
  childContainer.RegisterType<ObjectContext, MyContext>
     (new ContainerControlledLifetimeManager());
}

Application_EndRequest(...)
{
  var container = HttpContext.Items["container"] as IUnityContainer
  if(container != null)
    container.Dispose();
}
PHeiberg
Yeah i've seen this pattern, a similar one was proposed to my scenario in StructureMap (http://stackoverflow.com/questions/3665336/iqueryable-repository-with-structuremap-ioc-how-do-i-implement-idisposable) which you were also involved with. In the end, i didn't need to do this (thankfully, as i dont like the idea of creating DC's in begin/disposing in end).
RPM1984