我使用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
语句,并在RegisterServices
类的NinjectWebCommon
方法中,我可以看到在尝试使用此服务之前正在注册服务一,这不是问题。
任何人都知道为什么这总是空的?
答案 0 :(得分:2)
ASP.Net为您创建了MvcApplication
的实例,Ninject无法自动注入该属性。
当你提到注入在你的MVC应用程序的其他地方工作时,我假设你正在使用一个包含NinjectWebCommon
的Nuget包,其中包含在MVC应用程序中DI所需的所有管道。 NinjectWebCommon
将在Application_Start
事件之前运行,因为它可能会注册PreApplicationStartMethod
,除了注册您的依赖项之外,它还在后台为MVC配置IDependencyResolver
。< / p>
因此,您可以在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
?请参阅this other SO question或read this article。
这意味着您可以使用HttpApplication类的实例结束,其中服务和公司都为null。如果你只是想让公司在应用程序启动时使用并在后续事件中使用该对象,我会将VoucherCompany
设置为静态,在Application_Start上填充它并且甚至不愿意保存对服务的引用。 (根据您想要实现的目标,可能有更好的选择。)
希望它有所帮助!