2011-04-24 131 views
2

我有一個使用Ninject.Web.Mvc2和存儲庫模式(建立在實體框架模型上)的MVC 2.0應用程序。我正在嘗試創建一個新的ObjectContext,它只會在請求期間生存。我試圖通過以下方式來實現:Ninject PerRequest注入

protected override IKernel CreateKernel(){ 
    var kernel = new StandardKernel(); 
    kernel.Load(Assembly.GetExecutingAssembly()); 
    return kernel; 
} 

    protected override void OnApplicationStarted() 
    { 
     AreaRegistration.RegisterAllAreas(); 
     RegisterRoutes(RouteTable.Routes); 
    } 

然後我跑出去的想法,保持這種足夠通用的,所以我設置的的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]); 
    } 

包裝類僅僅是一個通用對象,用於在請求結束時包含我想要殺死的任何內容。在這種特殊情況下,我用它來製作新的ObjectContext也實現IDisposable,所以我可以做到以下幾點:

protected void Application_EndRequest() 
    { 
     foreach (var Item in HttpContext.Current.Items) 
     { 
      if (Item.GetType() == typeof(IPerRequestLifetimeObjectWrapper)) 
      { 
       (Item as IPerRequestLifetimeObjectWrapper).Dispose(); 
      } 
     } 
    } 

我敢肯定它不是這樣做的最漂亮的方式,但在這一點上我因爲我花了很多時間「學習」所有這些東西,所以我試圖讓自己動起來。然後

我的控制器被注入像這樣:

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)); 
    } 
} 

和我的倉庫被注入以及:

[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 
    } 

當我的控制器調用我的UserRepository內Get方法第一次它的工作原理大。如果我點擊刷新(或者我在猜測回傳),_db是空的。當我嘗試遍歷調試器時,我發現在調用Application_BeginRequest()之前調用Controller Index()方法。我以爲我對「管道」(我習慣於從WebForms調用頁面生命週期)有一個瞭解,但現在我有點失落。有人可以詳細說明我的大腦有一些電線穿過了嗎?就像我說的,這可能不是最漂亮的方法,但我只有約一週半的時間來學習MVC,使用Ninject,Repository和Entity Framework的DI,所以請不要覺得你在說話如果我覺得我打破了一些非常基本的東西的話。

+0

你不應該被'Bind'ing中的BeginRequest。看一個示例,並使用一個模塊來安置它們或者至少每個HttpApplication執行一次 – 2011-04-28 19:47:58

回答

1

爲什麼不直接使用InRequestScope?你所做的是爲每個請求添加一個新的綁定。這將導致嚴重的問題。 見https://github.com/ninject/ninject.web.mvc/wiki/Unit-of-work-pattern-with-nhibernate

這是NHilbernate但你可以做同樣的的EntityFramework

+0

對於所有這些,我還是很新的,所以我不瞭解InRequestScope。我一定會看看它。從我在網上看到的一覽看來,這正是我所需要的。謝謝! – SenseiHitokiri 2011-05-01 14:46:43