Andrew
Andrew

Reputation: 73

EF Context Management

What is the best way to manage the context of Entity Framework when using MVC application?

I am using a Repository/Service pattern.

Edit

After looking through some of these questions: stackoverflow.com/users/587920/sam-striano, I am more confused then before. Some say use the context per repository, but wht if I want to use multiple repositories in one controller method?

And to follow good separation design, how do you use UnitOfWork in the MVC app with out making it dependent on EF? I want to be able to unit test my controllers, model, services, etc. using a mock context?

Upvotes: 7

Views: 2282

Answers (2)

Omar
Omar

Reputation: 40202

Use a Dependency Injector/Inversion of Control framework like:

  1. Ninject
  2. Autofac
  3. StructureMap
  4. Unity

Using an IoC container, you can tell it how to manage a single data context (most commonly, per request). When you set the data context to per request, the container will auto-magically give any class that needs a data context the same data context per request.

Here is a good article on setting up Ninject.

What your code will most likely end up looking like, assuming you're using a generic repository:

Ninject Module:

public class NinjectRegistrationModule : NinjectModule
{
    public override void Load()
    {
        Bind<MyDataContext>().ToSelf().InRequestScope();
        Bind(typeof(RepositoryImplementation<>)).ToSelf().InRequestScope();

    }
}

Generic Repository:

public RepositoryImplementation<T> : IRepository<T> where T : class
{
    MyDataContext _dataContext;

    public RepositoryImplementation<T>(MyDataContext dataContext)
    {
        _dataContext = dataContext;
    }

    // bunch of methods that utilize _dataContext
}

Service Class:

public class MyServiceClass
{
    IRepository<SomeEntity> _someEntityRepository;

    public MyServiceClass(IRepository<SomeEntity> someEntityRepository)
    {
        _someEntityRepository = someEntityRepository;
    }

    // do stuff with _someEntityRepository = someEntityRepository;
}

Controller:

public class MyController
{
    MyServiceClass _myServiceClass;

    public MyController(MyServiceClass myServiceClass)
    {
        // Ninject will auto-magically give us a myServiceClass
        // which will Ninject will inject a repository into MyServiceClass's constructor
        _myServiceClass = myServiceClass;
    }

    public ActionResult MyAction()
    {
        // use _myServiceClass to do stuff
        return View();
    }
}

Upvotes: 6

smartcaveman
smartcaveman

Reputation: 42276

If your functionality is straight forward, then you should create a new ObjectContext in each Repository. They are cheap to instantiate.

If this creates a conflict, you can use a Unit of Work pattern as was suggested in the comment.

I would advise that you be extremely cautious when integrating an ObjectContext or DataContext with a DI container. Many do not use the appropriate scope for their life cycle by default.

Upvotes: 0

Related Questions