我可以为MvcApplication注入Ninject吗?

3
我正在使用ASP.NET MVC 5和Ninject 3。我希望网站启动时运行一些代码,从数据库中获取一些内容。我已经设置了注入并在项目的其他地方正常工作。我更改了Global.asax文件以使其看起来像这样...
[Inject]
public VoucherCompanyServiceLogicInterface VoucherCompanyServiceLogic { get; set; }

protected void Application_Start() {
  AreaRegistration.RegisterAllAreas();
  FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
  RouteConfig.RegisterRoutes(RouteTable.Routes);
  BundleConfig.RegisterBundles(BundleTable.Bundles);
  VoucherCompany vc = VoucherCompanyServiceLogic.GetByID(1, 1);
}

...但是VoucherCompanyServiceLogic属性始终为null。我将这两行代码(Inject属性和属性声明)从另一个类中复制过来,那个类中它们正常工作。

我在这个方法中放置了一些Debug.WriteLine语句,并且在NinjectWebCommon类的RegisterServices方法中也放置了一些语句,我可以看到服务在我尝试使用此服务之前已经被注册了,所以这不是问题所在。

有人知道为什么这总是为null吗?


很好的问题。这是因为在应用程序生命周期的那个点上,Ninject没有激活。您需要稍微重新考虑您的方法。我对Ninject不够了解,无法给您完整的答案。 - Rowan Freeman
你应该有一个类似于NinjectWebCommon的文件,找出它何时运行。正如Rowan Freeman所指出的那样,它可能还没有启动,这意味着此时它将无法注入你所需的内容。不过,在调用之前,你应该能够启动它。 - Kyle Gobel
感谢你们两位的回复,但是如果你们读一下我问题的倒数第二段,你们会发现我已经说了Ninject的东西在Application_Start代码之前运行过了。正如被接受的答案所指出的那样,问题在于Ninject没有参与MvcApplication对象的创建,因为它是由ASP.NET本身创建的。还是非常感谢。 - Avrohom Yisroel
1个回答

2

MvcApplication实例是由ASP.Net为您创建的,Ninject无法自动注入该属性。

由于您在MVC应用程序的其他位置中提到注入起作用,因此我假设您正在使用其中一个Nuget包,该包包括NinjectWebCommon和所有DI所需的管道。 NinjectWebCommon将在Application_Start事件之前运行,因为它可能注册了一个PreApplicationStartMethod,除了注册依赖项之外,它还在幕后为MVC配置了IDependencyResolver

因此,您可以在Application_Start方法中使用依赖项解析器来获取该服务的实例:

protected void Application_Start()
{        
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    VoucherCompanyServiceLogic = DependencyResolver.Current.GetService<IVoucherCompanyServiceLogicInterface>();
    if(VoucherCompanyServiceLogic != null)
    {
        VoucherCompany vc = VoucherCompanyServiceLogic.GetByID(1, 1);
    }
}

但是你计划如何使用那个 VoucherCompany 实例呢?你是否意识到 ASP.Net 可能会创建多个 MvcApplication 实例,并且不会为每个实例调用 Application_Start ?请参见此其他 SO 问题阅读此文章
这意味着你可能会得到 HttpApplication 类的实例,其中服务和公司都为空。如果你只想在应用程序启动时获得该公司,并且在随后的事件中有该对象可用,我建议将 VoucherCompany 设置为静态变量,在 Application_Start 上进行填充,甚至不必保存对服务的引用。(根据您想要实现的目标,可能会有更好的选择。)
希望对您有所帮助!

Daniel,感谢您的出色回复,特别是关于MvcApplication工作方式的解释。我没有意识到它可能会被多次调用。事实上,在我的情况下这不是问题,因为我打算填充一个静态对象,就像您建议的那样,并且只使用服务逻辑对象从数据库获取VC,而不是挂起它。我使用DependencyResolver来获取服务逻辑,它完美地工作了! - Avrohom Yisroel
很高兴听到这个消息,@Avrohom Yisroel。 (应用程序对象可能会有些棘手!) - Daniel J.G.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接