【发布时间】:2011-11-20 10:23:02
【问题描述】:
我已经在一个 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>();
}
}
【问题讨论】:
-
这里的关键问题是:谁在实例化 ReviewManager??
-
它是从任何 ASP.NET 代码隐藏中实例化的。
-
使用您的 ServiceLocator 还是使用新的 ReviewManager?
-
这就是它没有被注入的原因。如果您只是执行 new ReviewManager(),则无需注入其依赖项。您需要使用 ServiceLocator 来创建 ReviewManager...或者如果您希望它自动发生,请创建一个自定义处理程序工厂,如下所示 stackoverflow.com/questions/589374/…
-
那么这个属性的 [Inject] 属性的作用是什么: [Inject] private IReviewRepository _reviewRepository { get;放; }?在我看来,这应该向 Ninject 表明我希望它解决具体的实现......
标签: c# dependency-injection webforms inversion-of-control ninject