What is the best way to instantiate and dispose DbContext in MVC?

13,001

Solution 1

I would suggest you use a Dependency Injection framework. You can register your DbContext as per request

 container.RegisterType<MyDbContext>().InstancePerHttpRequest();

And inject it as a constructor parameter to the controller.

public class MyController : Controller
{
    public MyController(MyDbContext myDbContext)
    {
         _myDbContext = myDbContext;
    }
}

If the registered type implements IDisposable then the DI framework will dispose it when the request ends.

1st approach: It is much more cleaner to use ID framework than manually implementing it. Further all your requests may not need your UoW.

2nd approach: The controller should not know how to construct your UoW(DbContext). Purpose is not reduce the coupling between components.

Solution 2

We currently use repositories injected with UoW (unit of work) instantiated via service locator from an repository factory. Unity controls the lifetime this way taking the work away from you.

Your particular implementation will vary depending if your using POCO's, Entity Objects, etc..

Ultimately you want UoW if your going to be working with more than one objectset in your controller to ensure your just using one context. This will keep your transactions in check etc.

If your going to use multiple objectcontexts (ie. multiple EDMX's), you'll want to look at using UoW with MSDTC...but thats probably more than you wanted to know. In the end, the important thing is to ensure you just instantiate what you need for the controller action (i.e. one instance of the context.). I don't think I'd go with Begin_Request, you may not even need the context for every request.

Share:
13,001
YMC
Author by

YMC

Updated on June 03, 2022

Comments

  • YMC
    YMC almost 2 years

    MVC 3 + EF 4.1

    I'm choosing between two approaches to deal with DbContext:

    1. Instantiate in Application_BeginRequest, put it into HttpContext.Current.Items and dispose in Application_EndRequest.
    2. Create disposable UnitOfWork (kindof wrapper for DbContext) and start each controller action with using(var unitOfWork = new UnitOfWork()) { ... }

    Share your experience please: Which one would you prefer? what are pros and cons for each approach?

  • Thomas Levesque
    Thomas Levesque over 12 years
    The OP said nothing about putting the DbContext in a static field... he wants to put it in HttpContext.Current.Items, which is perfectly safe as far as I can see
  • YMC
    YMC over 12 years
    I did not say I put DbContext into global.asax. I said I put code that instantiates and disposes DbContext. DbContext is in HttpContext.Current.Items. It's thread-safe.
  • YMC
    YMC over 12 years
    Right, it's better to use IoC container than handling BeginRequset and EndRequest, but it still seems to me pretty close to number 1, that's why I've not even extracted it as separate approach. What is more important for me is to compare 2 ways to access and control life cycle of DbContext (=Unit Of work): first way implies ASP.NET/IoC infrastructure is responsible for it, second one is about every controller action to be in charge.
  • Eranga
    Eranga over 12 years
    @YMC Edited answer. Your 2nd approach will introduce coupling between your controller and UoW implementation. I suggest you avoid it.
  • marvelTracker
    marvelTracker over 12 years
    Introduce Service Layer and inject services to Controller. Service can have many repositories and repositories depend on UnitOfWork wrap with EFDbContext. Then use DI to inject those dependencies.Then You can get the advantage of Separation of Concerns.
  • Slauma
    Slauma over 12 years
    @Eranga: Does this mean that the context only gets instantiated if a controller is called which actually takes a context as constructor parameter? For example: If I have a controller with MyController() as constructor no context would be instantiated, right? If two controllers get called in one single request (could happen by using RenderAction for example) and both controllers have a context as parameter, only one context will be created and injected into both controllers, right? The example above isn't Unity, is it? Do you know if Unity2 offers such a logic too?
  • Eranga
    Eranga over 12 years
    @Slauma yes. DI framework takes care of it. example uses Autofac. I have seen "Per request lifetime" implementation of Unity on Silk