My web app solution consists of 3 projects:
I want to use Ninject to manage the lifetime of the DataContext
generated by the Entity Framework
in the Database Layer
.
The Business Logic layer consists of classes which reference repositories (located in the database layer) and my ASP.NET MVC app references the business logic layer's service classes to run code. Each repository creates an instance of the MyDataContext
object from the Entity Framework
Repository
public class MyRepository
{
private MyDataContext db;
public MyRepository
{
this.db = new MyDataContext();
}
// methods
}
Business Logic Classes
public class BizLogicClass
{
private MyRepository repos;
public MyRepository
{
this.repos = new MyRepository();
}
// do stuff with the repos
}
Will Ninject handle the lifetime of MyDataContext
despite the lengthy dependency chain from the Web App to the Data Layer?
Dependency injection is the principle that the objects which a class needs should be 'injected' into it, not created inside it. Injection usually happens through the constructor, where a class receives any objects it needs as constructor parameters.
Dependency Injection (DI) is a design pattern used to implement IoC. It allows the creation of dependent objects outside of a class and provides those objects to a class through different ways. Using DI, we move the creation and binding of the dependent objects outside of the class that depends on them.
Types of DI There are three main styles of dependency injection, according to Fowler: Constructor Injection (also known as Type 3), Setter Injection (also known as Type 2), and Interface Injection (also known as Type 1).
The fact your class has so many dependencies indicates there are more than one responsibilities within the class. Often there is an implicit domain concept waiting to be made explicit by identifying it and making it into its own service. Generally speaking, most classes should never need more than 4-5 dependencies.
EDIT
I has some problems with it some time ago, but now it seems to work:
Bind<CamelTrapEntities>().To<CamelTrapEntities>().Using<OnePerRequestBehavior>();
Instead of using HttpModule, you can use OnePerRequestBehavior and it will take care of handling context in current request.
EDIT 2
OnePerRequestBehavior needs to be registered in web.config, because it depends on HttpModule too:
In IIS6:
<system.web>
<httpModules>
<add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/>
</httpModules>
</system.web>
With IIS7:
<system.webServer>
<modules>
<add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/>
</modules>
</system.webServer>
PREVIOUS ANSWER
It is your responsibility to dispose context when it is not needed. Most popular way in ASP.NET is to have one ObjectContext per request. I do it by having HttpModule:
public class CamelTrapEntitiesHttpModule : IHttpModule
{
public void Init(HttpApplication application)
{
application.BeginRequest += ApplicationBeginRequest;
application.EndRequest += ApplicationEndRequest;
}
private void ApplicationEndRequest(object sender, EventArgs e)
{
((CamelTrapEntities) HttpContext.Current.Items[@"CamelTrapEntities"]).Dispose();
}
private static void ApplicationBeginRequest(Object source, EventArgs e)
{
HttpContext.Current.Items[@"CamelTrapEntities"] = new CamelTrapEntities();
}
}
This is injection rule:
Bind<CamelTrapEntities>().ToMethod(c => (CamelTrapEntities) HttpContext.Current.Items[@"CamelTrapEntities"]);
My Repository takes ObjectContext in constructor:
public Repository(CamelTrapEntities ctx)
{
_ctx = ctx;
}
Just want to mention that Autofac with the ASP.Net integration have the request lifetime support built-in. Resolve instances in the RequestContainer
and they will be disposed (if implementing IDisposable) at the end of the request.
You should make your classes DI friendly though:
public class MyRepository
{
private MyDataContext db;
public MyRepository(MyDataContext context)
{
this.db = context;
}
// methods
}
public class BizLogicClass
{
private MyRepository repos;
public BizLogicClass(MyRepository repository)
{
this.repos = repository;
}
// do stuff with the repos
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With