我一直在我的网络应用程序中使用Ninject作为我的IOC.这很好,我认为它工作得很好,但我一直在尝试将一些接口/类注册为OnePerRequestBehavIoUr,但它似乎并没有真正使用这种行为.代码运行正常但在我的一个类中,它延迟从数据库加载页面信息,然后一旦加载它就不需要命中数据库.
我的问题是,在我的第一个请求中加载了延迟加载的属性,然后我请求下一页使用该类的相同实例.我知道这个的原因是因为类没有再次实例化,并且已经设置了延迟加载的属性.
这段代码在我的模块类中:
public class NinjectModule : StandardModule { public override void Load() { Bind<IUnitOfWorkDataStore>().To<HttpContextDataStore>().Using<OnePerRequestBehavior>(); Bind<CmsService>().ToSelf().Using<OnePerRequestBehavior>(); Bind<CmsRepository>().ToSelf().Using<OnePerRequestBehavior>(); } }
然后在继承自NinjectHttpApplication的Global.asax中,我有以下内容:
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; }
对CmsService的第一次调用是在global.asax以及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 } }
上面的GetCurrentPage()代码:
public ContentPage GetCurrentPage() { if (_currentPage != null) return _currentPage; return GetCurrentPage(_isAdmin); }
所以你可以看到_currentPage变量只有在之前没有设置时才加载,每个请求应该是一次,但是Ninject似乎并没有按照请求创建CmsService它似乎创建了一个非常大量的时间.
Deos任何人都知道为什么这对我不起作用或任何示例代码肯定在哪里工作?
谢谢
解决方法
OnePerRequestModule是一个HttpModule,需要加载到您的ASP.NET管道才能工作.如果将其添加到web.config,它应该工作:
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>
在Ninject2(尚未发布)中,OnePerRequest行为得到了极大的改进.