簡體   English   中英

Ninject + ASP.NET Web窗體不起作用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM