How to access Entity Framework DbContext from MVC business objects?

I am starting a new ASP.NET MVC project. In my last project, one of the biggest smells of code was how I went through the Entity Framework DbContext, saved it in an HttpContext.Current called SaveChanges () in my rendering event, and did all kinds of (possibly indecent) related things.

Suppose my unit of work always matches the web request. What is the correct way to create a DbContext, pass this context to a business library (for example, an assembly outside the MVC project that is responsible for processing some workflow actions), return the result models back to my controller and save any changes?

To be honest, I know little about dependency injection. It seems that this should be connected, but I do not see how it will get me a common context instance between my controller and my business processes in the external assembly.

If I need it only from controllers, it would be easy. I would stick with HttpContext. But now the HttpContext has spread to my external library. Am I just defining an interface that returns the current DbContext, and based its implementation on HttpContext?

Hope it is clear that I ask, because I have lost a little.

+4
source share
1 answer

Injection injection definitely sounds like you are here. My preference is ninject, so the following is an example of how I do this with EF.

Install Ninject.MVC3 (available on nuget)

Go to \ app_start \ NinjectWebCommon.cs (added by the above package) and add the following to the RegisterServices method

kernel.Bind<MyContext>().ToSelf().InRequestScope(); //binding in the context in request scope, this will let us use it in our controllers 

Inside the controller, the context is used as follows

 public class MyController : ....{ private readonly MyContext _context; public MyController(MyContext context){ _context = context; } //Do stuff with _context in your actions } 

This is a very simple example for you to try, there are many better ways to structure this when your application grows (like ninject modules), but it will show how DI works.

A few notes: always make sure you bind the context in the requestcope (or more often), since DBContext has the unpleasant habit of growing pretty fast if it lasts too long.

In terms of sharing this with your external things that can also be introduced, for example

 public class MyExternalLogic{ public MyExternalLogic(MyContext context){....} } public class MyController : ....{ private readonly MyContext _context; public MyController(MyContext context, MyExternalLogic logic){ _context = context; ...} //Do stuff with _context in your actions } 

In the above example, the same DbContext instance will be used for both MyController and MyExternalLogic. Ninject will handle the creation of both objects.

There are also many other DI containers that will give you a very similar experience. I highly recommend DI as it helps a lot when using unit test.

A few more examples of how I use Ninject to structure my MVC applications, look at some of my projects on github, such as https://github.com/lukemcgregor/StaticVoid.Blog

+3
source

All Articles