Ninject.Web.PageBase仍然导致对注入依赖项的空引用 [英] Ninject.Web.PageBase still resulting in null reference to injected dependency

查看:104
本文介绍了Ninject.Web.PageBase仍然导致对注入依赖项的空引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用Ninject 2.0的ASP.NET 3.5 WebForms应用程序.但是,尝试使用Ninject.Web扩展名向System.Web.UI.Page提供注入,即使我切换为使用服务定位器提供引用(使用Ninject, ),没有问题.

I have an ASP.NET 3.5 WebForms application using Ninject 2.0. However, attempting to use the Ninject.Web extension to provide injection into System.Web.UI.Page, I'm getting a null reference to my injected dependency even though if I switch to using a service locator to provide the reference (using Ninject), there's no issue.

我的配置(为简单起见,将其简化):

My configuration (dumbed down for simplicity):

public partial class Default : PageBase // which is Ninject.Web.PageBase
{
    [Inject]
    public IClubRepository Repository { get; set; }

    protected void Page_Load(object sender, EventArgs e)
    {
        var something = Repository.GetById(1); // results in null reference exception.
    }
 }

... //global.asax.cs

... //global.asax.cs

public class Global : Ninject.Web.NinjectHttpApplication
{
    /// <summary>
    /// Creates a Ninject kernel that will be used to inject objects.
    /// </summary>
    /// <returns>
    /// The created kernel.
    /// </returns>
    protected override IKernel CreateKernel()
    {
        IKernel kernel =
        new StandardKernel(new MyModule());
        return kernel;

    }

..

...

public class MyModule : NinjectModule
{
    public override void Load()
    {
        Bind<IClubRepository>().To<ClubRepository>();
        //...
    }
}

通过服务定位器获取IClubRepository具体实例工作正常(使用相同的"MyModule"). IE.

Getting the IClubRepository concrete instance via a service locator works fine (uses same "MyModule"). I.e.

  private readonly IClubRepository _repository = Core.Infrastructure.IoC.TypeResolver.Get<IClubRepository>();

我想念什么?

[更新]终于回到了这一点,它可以在经典管道"模式下工作,但不能在集成"模式下工作.是经典管道吗?

[Update] Finally got back to this, and it works in Classic Pipeline mode, but not Integrated. Is the classic pipeline a requirement?

[更新2]是我的OnePerRequestModule的连接问题(为清楚起见,在上面的示例中已将其删除):

[Update 2] Wiring up my OnePerRequestModule was the problem (which had removed in above example for clarity):

    protected override IKernel CreateKernel()
    {
        var module = new OnePerRequestModule();
        module.Init(this);

        IKernel kernel = new StandardKernel(new MyModule());

        return kernel;
    }

...需要是:

    protected override IKernel CreateKernel()
    {
        IKernel kernel = new StandardKernel(new MyModule());

        var module = new OnePerRequestModule();
        module.Init(this);

        return kernel;
    }

因此解释了为什么在集成管道下(对于Ninject注入的依赖项,或者只是从Ninject.Web.PageBase继承的页面的页面加载-无论先发生什么),都会得到null引用异常.

Thus explaining why I was getting a null reference exception under integrated pipeline (to a Ninject injected dependency, or just a page load for a page inheriting from Ninject.Web.PageBase - whatever came first).

推荐答案

这很令人困惑,因为从我的判断来看,您似乎已经正确配置了所有内容.从您得到的是Null引用异常而不是ActivationException的事实来看,似乎没有发生页面级注入.通常,这是由于注入了属性的保护级别引起的,但是根据您的代码,那里没有问题.您可以尝试以下一些方法来帮助找出问题所在:

This is fairly puzzling because from what I can tell it appears that you have everything configured correctly. From the fact that you are getting a Null Reference Exception instead of an ActivationException, it would seem that the page level injection does not appear to be happening. Typically this is due to the protection level of the property being injected, but based on your code there is no issue there. Here are some things you can try to help track down what this issue is:

  1. 对Kernel.Inject(this)的调用(用于为Ninject启动属性注入)是在PageBase类的OnInit方法中完成的.如果由于某种原因该方法未执行,则可能会导致您看到的问题.您可以通过重写RequestActivation()方法进行进一步的研究,该方法是实际注入所调用的方法(一定要调用base.RequestActivation()).如果您的覆盖从未被调用,则OnInit会出现问题.

  1. The call to Kernel.Inject(this), which initiates the property injection for Ninject is done in the OnInit method of the PageBase class. If for some reason this method is not getting executed it could result in the issue your seeing. You can do some further investigation by overriding the RequestActivation() method, which is the method called to do the actual injection (be sure to call base.RequestActivation()). If your override is never called, then there is an issue with the OnInit.

InjectAttribute是在默认内核配置中设置的,因此不需要指定它,但是,如果您想更加确定一点,可以在内核设置中设置属性映射,方法是:做类似的事情:

The InjectAttribute is set up in the default kernel configuration, so there should not be any need to specify it, however if you wanted to be extra certain, you could set up the attribute mapping in your kernel set up by doing something like:

IKernel内核=新的StandardKernel(新的NinjectSettings {InjectAttribute = typeof(InjectAttribute)},新的MyModule());

IKernel kernel = new StandardKernel(new NinjectSettings { InjectAttribute = typeof(InjectAttribute) },new MyModule());

由PageBase类用于注入的内核实例(同样应由Global.asax.cs中的CreateKernel重写实例化的实例)存储在Ninject.Web中的服务定位器类型对象中.KernelContainer.我将确保您可以在KernelContainer上看到Kernel属性,并且该属性在您的Page_Load方法中不为空.

The kernel instance used by the PageBase class for the injection (and likewise the one that should be instantiated by your CreateKernel override in your Global.asax.cs) is stored in a service locator type object in Ninject.Web.KernelContainer. I would make sure you can see the Kernel property on KernelContainer and that it is not null from your Page_Load method.

就目前的洞察力而言,这就是我所拥有的.就像我说的,从这里看来,所有的鸭子都穿好衣服并排成一排,所以它们应该在工作....

Thats all I've got at the moment as far as insight. Like I said it appears from here that you have all of your ducks dressed and put in rows, so they should be working....

祝您顺利找到问题所在.

Good luck tracking down the issue.

这篇关于Ninject.Web.PageBase仍然导致对注入依赖项的空引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆