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

查看:24
本文介绍了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 继承的页面的页面加载 - 无论先发生什么).

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 Reference Exception 而不是 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) 的调用是在 PageBase 类的 OnInit 方法中完成的,它启动了 Ninject 的属性注入.如果由于某种原因此方法没有被执行,它可能会导致您看到的问题.您可以通过覆盖 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 kernel = new StandardKernel(new NinjectSettings { InjectAttribute = typeof(InjectAttribute) },new MyModule());

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

PageBase 类用于注入的内核实例(同样应该由 Global.asax.cs 中的 CreateKernel 覆盖实例化的内核实例)存储在 Ninject.Web 中的服务定位器类型对象中.内核容器.我会确保您可以在 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....

祝你好运追查问题.

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

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