2009-02-11 9 views
6

Tôi đã sử dụng Ninject làm IOC trong ứng dụng web của mình. It's tuyệt vời và tôi nghĩ rằng nó hoạt động thực sự tốt, tuy nhiên tôi đã cố gắng để đăng ký một số giao diện/lớp học như OnePerRequestBehaviour nhưng nó dường như không thực sự sử dụng hành vi. Mã chạy một cách chính xác nhưng trong một trong các lớp của tôi nó tải thông tin trang từ cơ sở dữ liệu sau đó một khi nó đã được nạp nó không cần phải nhấn cơ sở dữ liệu.Ninject OnePerRequestBehaviour dường như không hoạt động chính xác?

Vấn đề của tôi là thuộc tính được tải lazily sẽ tải trong yêu cầu đầu tiên của tôi, khi tôi yêu cầu trang tiếp theo cùng một thể hiện của lớp được sử dụng. Lý do tôi biết điều này là do lớp không được khởi tạo lại và thuộc tính được nạp lazily đã được thiết lập.

Mã này nằm trong lớp mô-đun của tôi:

public class NinjectModule : StandardModule 
{ 
    public override void Load() 
    { 
     Bind<IUnitOfWorkDataStore>().To<HttpContextDataStore>().Using<OnePerRequestBehavior>(); 


     Bind<CmsService>().ToSelf().Using<OnePerRequestBehavior>(); 
     Bind<CmsRepository>().ToSelf().Using<OnePerRequestBehavior>(); 
    } 
} 

Sau đó bên trong Global.asax của tôi mà được thừa hưởng từ NinjectHttpApplication Tôi đã điều sau đây:

 protected override IKernel CreateKernel() 
     { 
      OnePerRequestModule module = new OnePerRequestModule(); 
      module.Init(this); 

      KernelOptions options = new KernelOptions(); 
      options.InjectNonPublicMembers = true; 

      IKernel kernel = new StandardKernel(options, new NinjectModule()); 

      return kernel; 
     } 

Cuộc gọi đầu tiên thực hiện để CmsService nằm trong global.asax cũng như trên authenticate_request:

protected void Application_AuthenticateRequest(object sender, EventArgs e) 
     { 
      if (HttpContext.Current.Request.Url.AbsoluteUri.Contains(".aspx") && 
       !HttpContext.Current.Request.Url.AbsoluteUri.Contains(".aspx/")) 
      { 
       CmsService facCMS = HttpKernelFactory.Get<CmsService>(); 
       ContentPage page = facCMS.GetCurrentPage(); 

       // DO Logic based on the page being brought back 
      } 
     } 

T ông trên GetCurrentPage() code:

public ContentPage GetCurrentPage() 
{ 
    if (_currentPage != null) 
     return _currentPage; 

    return GetCurrentPage(_isAdmin); 
} 

Như bạn có thể thấy các biến _currentPage chỉ được nạp nếu nó chưa được cài đặt trước đó, mà nên có một lần theo yêu cầu, tuy nhiên Ninject dường như không được tạo CmsService theo yêu cầu có vẻ như tạo ra nó cho một khoảng thời gian abritrary.

Bất cứ ai có bất kỳ ý tưởng nào về lý do tại sao điều này không hiệu quả đối với tôi hoặc bất kỳ mã ví dụ nào về việc nó hoạt động đúng cách?

Cảm ơn

Trả lời

8

Các OnePerRequestModule là một HttpModule, và cần phải được nạp vào đường ống ASP.NET của bạn để làm việc. Nếu bạn thêm nó vào web.config của bạn, nó sẽ làm việc:

IIS7:

<system.webServer> 
    <modules> 
    <add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/> 
    </modules> 
</system.webServer> 

IIS6:

<system.web> 
    <httpModules> 
    <add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/> 
    </httpModules> 
</system.web> 

Các hành vi OnePerRequest được cải thiện rất nhiều trong Ninject2 (đó là chưa được phát hành).

+1

Phát hiện cảm ơn, nhưng sau đó tôi đoán câu trả lời sẽ không sai với người sáng tạo! Ninject thực sự tốt, tôi thích nó. Bất kỳ ý tưởng nào khi bạn hy vọng Ninject2 sẽ được phát hành? –