Ninject.Web.PageBase仍导致对注入依赖项的null引用

时间:2010-03-01 18:41:10

标签: asp.net ninject webforms

我有一个使用Ninject 2.0的ASP.NET 3.5 WebForms应用程序。但是,尝试使用Ninject.Web扩展来向System.Web.UI.Page提供注入,即使我切换到使用服务定位器来提供引用,我也会得到对我注入的依赖项的空引用(使用Ninject ),没有问题。

我的配置(为简单而愚蠢):

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

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”)。即

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

我错过了什么?

[更新]最后回到这个,它在Classic Pipeline模式下工作,但不是Integrated。经典管道是否需要?

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

    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继承的页面的页面加载 - 无论什么是第一个)。

2 个答案:

答案 0 :(得分:2)

这是相当令人费解的,因为据我所知,您似乎已正确配置了所有内容。从您获得Null引用异常而不是ActivationException的事实来看,似乎页面级别注入似乎没有发生。通常这是由于注入的属性的保护级别,但根据您的代码,没有问题。以下是您可以尝试帮助追踪此问题的一些事项:

  1. 调用Kernel.Inject(this),它启动Ninject的属性注入,是在PageBase类的OnInit方法中完成的。如果由于某种原因这个方法没有被执行,可能会导致你看到的问题。您可以通过覆盖RequestActivation()方法进行进一步调查,该方法是调用实际注入的方法(请务必调用base.RequestActivation())。如果从未调用过覆盖,则OnInit存在问题。

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

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

  3. PageBase类用于注入的内核实例(以及应该由Global.asax.cs中的CreateKernel覆盖实例化的内核实例)存储在Ninject.Web中的服务定位器类型对象中。 .KernelContainer。我会确保你可以在KernelContainer上看到Kernel属性,并且你的Page_Load方法它不是null。

  4. 就目前而言,我所拥有的只有洞察力。就像我说的那样,从这里可以看出你所有的鸭子都穿好了并且排成一排,所以他们应该工作......

    祝你好运追踪这个问题。

答案 1 :(得分:1)

这可能不是Ninject特有的。我可以在没有IoC的集成模式下运行相同的异常。我只有一个简单的asp.net应用程序,它只包含一个没有逻辑的aspx页面。

在我的global.asax文件中,我有以下内容:

public class Global : HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        this.EndRequest += new EventHandler(Global_EndRequest);
    }

    void Global_EndRequest(object sender, EventArgs e)
    {
        // do stuff
    }

在集成管道模式下运行时,基本上订阅application_start中的事件会导致此异常。切换到经典管道或删除事件订阅和处理程序会使错误消失。我在Win7 Enterprise 64bit上运行IIS 7.5。

这可能无法解决您的具体问题,但我在这里发布,因为这是我将该异常粘贴到Google时出现的唯一页面!当我被允许问一个问题时,我会将我的答案移到一个单独的问题中。我还没有stackoverflow的赞誉:(