[英]Ninject + ASP.NET Web Forms Not Working
我已經在MVC3應用程序中成功實現了Ninject,但是在使用ASP.NET Web窗體執行相同操作時遇到了一些麻煩。 每次嘗試訪問業務層中的注入屬性時,都會得到空引用。 在CreateKernel方法中以及ServiceLocator類中的多個位置上設置斷點后,似乎沒有一個碰到過中斷,因此甚至沒有加載。
我敢肯定我正在解決這個錯誤,但是在Web Forms應用程序中連接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>();
}
}
通過WebForms的ASP.Net不允許您管理所有對象實例的生命周期(就像MVC一樣)。 例如,框架實例化頁面對象。 這意味着您可能無法以與在MVC / WPF / Silverlight中完全相同的方式實現DI(WinForms IIRC中存在相同的問題)。 您可能必須直接在每個代碼背后都啟動依賴關系圖。
轉換:您需要在頁面加載時(或在屬性上作為lazy-init)調用ServiceLocator.Kernel.Get<IReviewRepository>
。
關於MVC的很酷的事情是它可以在同一應用程序中同時運行ASP.NET WebForm頁面。 我認為擴展ASP.NET WebForms網站的最佳方法是使用MVC3創建新頁面,並重構需要對MVC3進行重大更改的每個頁面。
如果沒有選擇,請使用Ninject.Web擴展名。 它包含一個IHttpModule,該屬性將在初始化所有網頁和控件后注入所有網頁和控件。 這樣,您可以屬性注入由Ninject創建的服務。
我將屬性注入用於頁面,母版頁和用戶控件。 例如,我的所有頁面均從基類繼承,該基類使用以下代碼重寫RequestActivation
方法:
''' <summary>
''' Asks the kernel to inject this instance.
''' </summary>
Protected Overridable Sub RequestActivation()
ServiceLocator.Kernel.Inject(Me)
End Sub
在每個頁面中,我聲明可注入屬性:
<Inject()>
Property repo As IMyRepository
通過如下更改您的DataBindings類,可能的解決方法:
public class DataBindings : NinjectModule
{
public override void Load()
{
Bind<IReviewRepository>().To<ReviewRepository>();
Bind<ReviewManager>().ToSelf();
}
}
在您的呼叫者內,而不是
var rm = new ReviewManager();
嘗試使用
var rm = ServiceLocator.Kernel.Get<ReviewManager>();
我尚未測試此代碼,但我認為它將解決您的null引用問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.