Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Share DbContext across Repositories in MVC Web App

Question

What is the proper way to share an EF DbContext across multiple repositories in an MVC web app? Is it prudent/necessary to do so, what are the pitfalls of doing or not doing this?

Background

Assume:

  • App.MvcSite (Several dozen controllers, multiple areas, etc)
  • App.Services (service layer, many services)
  • App.Data (many repositories, etc)
  • ... etc excluded for simplicity (EF Code First latest)

Research To Date

I seem to find at least two/three schools of thought on SO and the interwebs.

  1. Share/scope your DbContext to the Request so that a single request has a single DbContext shared by all repositories.
  2. Share/scope your DbContext at the service layer -- the service maintains a single DbContext and passes it to each repository as needed.
  3. Do not share a DbContext, since they are cheap let each Repo have its own.

In a small website this is a non-issue which is why most MS and community examples simply don't even address this.

In my experience thus far I have not used finite repositories. I have always had services use a DbContext and directly change it so I didn't need to worry about this. I'm told there is a great benefit to finite repositories from a unit testing perspective... we'll see if it makes the rest of this worthwhile.

My Thoughts

(1) Share/scope your DbContext to the Request

This is interesting as it smartly avoids the pitfall of a singleton context which some developers think is the answer but find DbContext doesn't work that way. But it seems to have a downside in that it assumes all repositories, services, etc are going to be in coordination across an entire request... this is often not the case, right? What if changes are saved by one repo before another completes its work. (outer(inner(inner)))

(2) Share/scope your DbContext at the service layer

This makes more sense to me because each service should be coordinating a specific unit of work (lower case intentional). So if multiple services were used in one request it would be proper (if not required) that each had its own context to the database.

(3) Do not share a DbContext, since they are cheap

This is the way I've always done it... well actually I almost always only had one DbContext per request because only one service was being called. Sometimes it might be two because two services were called by a controller who was coordinating the work. But given my current application, with many finite repositories, each repository having its own context would mean a given request might have 3-10 instances of DbContext. I assume (perhaps incorrectly) that this is problematic.


Repeating the question:

What is the proper way to share an EF DbContext across multiple repositories in an MVC web app? Is it prudent/necessary to do so, what are the pitfalls of doing or not doing this?

like image 403
kingdango Avatar asked Feb 27 '13 13:02

kingdango


2 Answers

  • DbContext are cheap, but distributed transactions are not.
  • Objects attached to one context can't be used in another context (if you have object relations)

The easiest way to share a context is to start using an inversion of control container: http://www.codeproject.com/Articles/386164/Get-injected-into-the-world-of-inverted-dependenci

like image 76
jgauffin Avatar answered Oct 07 '22 07:10

jgauffin


I would go for a combination between the first two options and regarding your take on the first option, don't let repositories save any changes (that's not the recommended way of doing things, Martin Fowler says that him self) and for that he introduced the Unit of Work pattern.

like image 23
Ibrahim Najjar Avatar answered Oct 07 '22 08:10

Ibrahim Najjar