代码之家  ›  专栏  ›  技术社区  ›  Ted

ninject.web.pagebase仍然导致对注入依赖项的空引用

  •  5
  • Ted  · 技术社区  · 16 年前

    我有一个使用ninject 2.0的asp.net 3.5webforms应用程序。但是,尝试使用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.
        }
     }
    

    … //全局.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>();
    

    我错过了什么?

    [更新]最后回到这个,它在经典的流水线模式下工作,但没有集成。传统的管道是一个要求吗?

    [更新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 回复  |  直到 16 年前
        1
  •  2
  •   ckramer    16 年前

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

    1. 对kernel.inject(this)的调用是在PageBase类的onInit方法中完成的,该调用启动了Ninject的属性注入。如果由于某种原因这个方法没有被执行,它可能会导致您看到的问题。您可以通过重写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方法中它不为空。

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

    祝你找到问题所在。

        2
  •  1
  •   rob bentley    16 年前

    这可能不是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
        }
    

    基本上,订阅应用程序启动中的事件会导致在集成管道模式下运行时出现此异常。切换到经典管道或删除事件订阅和处理程序会使错误消失。我在win7 enterprise 64bit上运行iis 7.5。

    这可能无法解决你的具体问题,但我在这里张贴,因为这是唯一一个网页,当我粘贴到谷歌例外!当我被允许问一个问题时,我会把我的答案换成另一个问题。我还没有斯塔克弗洛夫的荣誉:(

    推荐文章