忍者+ ASP.NET Web 表单不工作
我已经在 MVC3 应用程序中成功实现了 Ninject,但在使用 ASP.NET Web 窗体执行同样的操作时遇到了一些麻烦。每次尝试访问业务层中的注入属性时,我都会收到空引用。在 CreateKernel 方法中以及 ServiceLocator 类中的多个位置设置断点后,看起来它们都没有被击中,因此它甚至没有加载。
我确信我的做法是错误的,但是在 Web 表单应用程序中连接 Ninject 的文档或信息非常少。
基本上这就是我到目前为止所拥有的:
代码隐藏
public class ReviewManager
{
[Inject] private IReviewRepository _reviewRepository { get; set; }
public ReviewManager() { }
public ReviewManager(IReviewRepository reviewRepository)
{
_reviewRepository = reviewRepository;
}
public Review GetById(int id)
{
if (id <= 0) throw new ArgumentException("ID must be greater than zero");
**I get a null reference exception on the next line. _reviewRepository is null**
return _reviewRepository.GetById(id);
}
}
global.asax.cs
public class Global : NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
return ServiceLocator.Kernel;
}
// deleted for brevity
}
ServiceLocator.cs (为简洁起见,相关部分位于此处)
public static class ServiceLocator
{
public static IKernel Kernel { get; set; }
public static ILogger Logger { get; set; }
static ServiceLocator()
{
Kernel = new StandardKernel(new INinjectModule[] {
new LoggerBindings(),
new DataBindings()
});
if (Logger == null)
Logger = Kernel.Get<ILogger>();
}
}
public class LoggerBindings : NinjectModule
{
public override void Load()
{
Bind<ILogger>().To<NLogLogger>();
}
}
public class DataBindings : NinjectModule
{
public override void Load()
{
Bind<IReviewRepository>().To<ReviewRepository>();
}
}
I've successfully implemented Ninject in an MVC3 application, but am running into some trouble doing the same thing with ASP.NET Web Forms. I'm getting null references every time I try to access an injected property in my business layer. After setting breakpoints within the CreateKernel method, as well as several places within the ServiceLocator class, it looks like none of them are ever getting hit, so it's not even loading.
I'm sure I'm just approaching this wrong, but there is very little documentation or info out there for wiring up Ninject in a Web Forms application.
Basically here's what I have so far:
code behind
public class ReviewManager
{
[Inject] private IReviewRepository _reviewRepository { get; set; }
public ReviewManager() { }
public ReviewManager(IReviewRepository reviewRepository)
{
_reviewRepository = reviewRepository;
}
public Review GetById(int id)
{
if (id <= 0) throw new ArgumentException("ID must be greater than zero");
**I get a null reference exception on the next line. _reviewRepository is null**
return _reviewRepository.GetById(id);
}
}
global.asax.cs
public class Global : NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
return ServiceLocator.Kernel;
}
// deleted for brevity
}
ServiceLocator.cs (edited for brevity, the relevant parts are here)
public static class ServiceLocator
{
public static IKernel Kernel { get; set; }
public static ILogger Logger { get; set; }
static ServiceLocator()
{
Kernel = new StandardKernel(new INinjectModule[] {
new LoggerBindings(),
new DataBindings()
});
if (Logger == null)
Logger = Kernel.Get<ILogger>();
}
}
public class LoggerBindings : NinjectModule
{
public override void Load()
{
Bind<ILogger>().To<NLogLogger>();
}
}
public class DataBindings : NinjectModule
{
public override void Load()
{
Bind<IReviewRepository>().To<ReviewRepository>();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
通过 WebForms 的 ASP.Net 不允许您管理所有对象实例的生命周期(像 MVC 那样)。例如,框架实例化页面对象。这意味着您可能无法以与在 MVC/WPF/Silverlight 中完全相同的方式实现 DI(WinForms IIRC 中也存在同样的问题)。您可能必须直接在每个后面的代码中启动依赖关系图。
翻译:您需要在页面加载时调用
ServiceLocator.Kernel.Get
(或作为属性上的惰性初始化)。ASP.Net via WebForms does not allow you to manage the lifecycle of all object instances (like MVC does). For example, the framework instantiates page objects. This means you probably can't implement DI in quite the same way as you would in MVC/WPF/Silverlight (the same problem is present in WinForms IIRC). You will likely have to initiate the dependency graph directly in each of your code behinds.
Translation: you will want to call
ServiceLocator.Kernel.Get<IReviewRepository>
when your page loads (or as lazy-init on the property).MVC 的一个很酷的地方是它可以在同一个应用程序中同时运行 ASP.NET WebForm 页面。在我看来,扩展 ASP.NET WebForms 网站的最佳方法是使用 MVC3 创建新页面,并重构每个需要对 MVC3 进行重大更改的页面。
如果这不是选项,请使用 Ninject.Web 扩展。它包含一个 IHttpModule,该属性在初始化后注入所有网页和控件。这样您就可以属性注入由 Ninject 创建的服务。
The cool thing about MVC ist that it can run side a side of ASP.NET WebForm pages in the same application. In my opinion the best way to extend ASP.NET WebForms websites is to create new pages using MVC3 and to refactor every page that needs major changes to MVC3.
If this is no option go and use the Ninject.Web extension. It contains a IHttpModule that property injects all web pages and controlls after they are initialized. That way you can property inject the services als have them created by Ninject.
一个潜在的解决方法是,通过如下更改您的 DataBindings 类:
在您的调用者中,不要
尝试使用
我还没有测试过此代码,但我认为它会解决您的空引用问题。
A potential workaround, by changing your DataBindings class as follows:
And within your caller, instead of
Try using
I havent tested this code, but i think it'll solve your null reference problem.
我对页面、母版页和用户控件使用属性注入。例如,我的所有页面都继承自一个基类,该基类使用以下代码覆盖
RequestActivation
方法:并且在每个页面中我声明可注入属性:
I use property injection for pages, masterpages and usercontrols. All my pages, for example, inherit from a base class that overrides
RequestActivation
method with the following code:And in each page I declare injectable properties: