我使用nuget模板的方式来注入我的MVC3应用程序,这意味着我必须使用WebActivator在静态类上调用一个方法,该方法反过来创建一个Ninject引导程序并连接到MVC3。
这对Controller、适配器等都很好。但我希望有另一个Webactivator激活的类,它可以使用Ninject获得依赖项。
我用了一个穷人的解决方案,但我更喜欢一个更优雅的解决方案。
首先,我确保我的Webactivator类使用PostApplicationStartMethod调用,因为Ninject模块使用PreApplicationStartMethod,所以我可以确保Ninject已经加载并准备就绪。。THen在启动方法中我做
var workers = DependencyResolver.Current.GetServices<IWorker>();
为了获得我的依赖项,整个类看起来像这个
[assembly: WebActivator.PostApplicationStartMethod(typeof(SHB.DALA.Web.App_Start.WorkflowRunner), "Start")]
namespace SHB.DALA.Web.App_Start
{
public static class WorkflowRunner
{
public static void Start()
{
var workers = DependencyResolver.Current.GetServices<IWorker>();
//Do stuff with worker collection
}
}
}
一定有一个更优雅的解决方案,对吧?
WebActivator(ASP.NET(对Ninject项目一无所知,因此无法注入任何参数。你需要一个Ninject WebActivator扩展(就像你有Ninject MVC扩展一样(来实现它。但坦率地说,这有点像第二十二条陷阱:你希望WebActivator设置Ninject,同时Ninject设置WebActivator。
我可以为你想出两种可能的情况:
-
让代码保持原样——我真的不知道你为什么不喜欢你的
WorkflowRunner
类。它是一个很好的小类,没有其他代码对它有任何依赖。你通过DependencyResolver
获得引用,它将你从Ninject本身中抽象出来,你的工作流初始化被很好地封装在那里。真的,我在这里没有闻到任何臭味。 -
在另一个WebActivator类中初始化工作流,在该类中设置Ninject。您知道您的Ninject已经初始化,并且您仍然可以将工作流初始化代码保存在一个单独的类中。
我显然会选择1。如果我是你。
如果您已经有了Ninject引导程序,您确定需要另一个解决方案吗?对于非控制器依赖项,我使用BindingFactory类,该类具有GetInstance((方法。这只是调用Kernel对象上的Get((方法。
public class BindingFactory
{
private static readonly IKernel Kernel = new StandardKernel(new DefaultServices());
public static T GetInstance<T>()
{
return Kernel.Get<T>();
}
public static IController GetControllerInstance(Type controllerType)
{
return Kernel.Get(controllerType) as IController;
}
}
然后,我使用一个使用BindingFactory的NinjectControllerFactory。
public class NinjectControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext context, Type controllerType)
{
if (controllerType == null)
return null;
return BindingFactory.GetControllerInstance(controllerType);
}
}
所以我认为您可以调整当前的实现方式。