Ninject PerRequest injection
I have a MVC 2.0 application using Ninject.Web.Mvc2 and a repository pattern (built over an entity framework model ). I am trying to create a new ObjectContext that will only live for the duration of the request. I am attempting to accomplish this in the following manner:
protected override IKernel CreateKernel(){
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
return kernel;
}
protected override void OnApplicationStarted()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
I then ran out of ideas for keeping this generic enoug开发者_开发百科h so I set to work in the BeginRequest:
protected void Application_BeginRequest()
{
string EntityConnectionString = ConfigurationManager.ConnectionStrings["Entities"].ConnectionString;
HttpContext.Current.Items.Add(_PerRequestContextObjectKey, new EntityFrameworkContextWrapper(EntityConnectionString));
this.Kernel.Bind<IUserRepository>().To<UserRepository>().WithConstructorArgument("ContextWrapper", HttpContext.Current.Items[_PerRequestContextObjectKey]);
}
The Wrapper class is just a generic object for including anything I want to kill at the end of request. In this specific case, I use it to create my new ObjectContext and also implement IDisposable so I can do the following:
protected void Application_EndRequest()
{
foreach (var Item in HttpContext.Current.Items)
{
if (Item.GetType() == typeof(IPerRequestLifetimeObjectWrapper))
{
(Item as IPerRequestLifetimeObjectWrapper).Dispose();
}
}
}
I'm sure it's not the prettiest way of doing this, but at this point I'm trying to get moving since I've spent so much time "learning" all this stuff.
My Controller is then injected like so:
public class AdminUserController : Controller
{
// Mark for Ninject
[Inject] public IUserRepository _userRepo { get; set; }
public ViewResult Index( )
{
return View(_userRepo.Get);
}
public ViewResult Edit(Guid UserUID)
{
return View(_userRepo.GetById(UserUID));
}
}
and my Repository gets injected as well:
[Inject]
public UserRepository(EntityFrameworkContextWrapper ContextWrapper )
// Mark for Ninject Dependency Injection
// Must receive Wrapper that contains active ObjectContext
{
_db = ContextWrapper.Entities; //Not actually named this, just easier for typing right now
}
When my Controller calls the Get method inside my UserRepository object the first time it works great. If I hit refresh ( or I'm guessing postback as well ), _db is Null. When I try to step through the debugger, I find that the Controller Index( ) method is being called before a Application_BeginRequest() is called. I thought I had an understanding of the "pipeline" ( I'm used to calling things page lifecycle from WebForms ), but now I'm a bit lost. Can someone elaborate on where my brain has some wires crossed? Like I said, this probably isn't the prettiest method, but I've only had about a week and a half to learn MVC, DI with Ninject, Repository, and Entity Framework so please don't feel like you're talking down to me if it seems like I broke something very basic.
Why don't you simply use InRequestScope? What you do is adding a new binding for each request. This will lead to severe problems. See https://github.com/ninject/ninject.web.mvc/wiki/Unit-of-work-pattern-with-nhibernate
It's NHilbernate but you can do the same with EntityFramework
精彩评论