如何在应用程序中组织DI框架的使用?
编辑:我忘了把内核移到这里的非泛型父类,并提供一个虚拟的方法来访问它。我意识到下面的例子会创建大量的内核实例。如何在应用程序中组织DI框架的使用?
我只是学会了如何做注射过去的这个星期,这里是我是如何得到的东西设置了目前:
using Ninject;
using System.Reflection;
namespace Infrastructure
{
public static class Inject<T>
{
static bool b = Bootstrap();
static IKernel kernel;
static bool Bootstrap()
{
kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
return true;
}
public static T New() { return kernel.Get<T>(); }
}
}
然后我打算做基础设施的命名空间的各种ninject模块类一部分,所以这会加载它们。
我一直没能在这里找到任何东西,或者Google给出了如何在您的项目中实际组织使用Ninject的示例,但这对我来说似乎是正确的,因为它允许我只需要Ninject参考这个组装。这是多少有点“正确”的方式,还是有更好的设计?
现在你如何做事情有几个问题。
让我先从明显的C#问题开始:泛型类中的静态类变量是基于每个T
共享的。换句话说,Inject<IUserRepository>
和Inject<IOrderRepository>
将分别获得自己的IKernel
实例,这不太可能是您真正想要的实例,因为它很可能在您的应用程序的生命周期中需要单个IKernel
。如果应用程序没有单一的IKernel
,则无法将类型注册为单例,因为单例总是在容器级而不是在应用程序级。所以,你最好重写类非通用和移动泛型类型参数的方法:
Inject.New<T>()
第二个问题是一个关注的依赖注入。在我看来,您正在尝试使用Service Locator anti-pattern,因为您可能在应用程序内明确地调用了Inject.New<T>
。只能在应用程序的启动路径中引用DI容器,并且应该能够构造相关对象的完整对象图。通过这种方式,您可以要求容器为您获取根级别的对象(例如,在MVC的上下文中为Controller
),并且应用程序的其余部分将不会使用任何DI技术。当你这样做时,没有必要将容器的使用抽象出来(就像你使用类Inject
一样)。
并非所有应用程序或UI技术都允许此BTW。在使用Web窗体应用程序时,我倾向于隐藏我的容器(就像您在做什么一样),因为无法在Page
类,IHttpHandler
对象和UserControl
类上执行适当的依赖项注入。
其实我知道每个T的泛型静态成员,我有办法通过将静态成员移动到非泛型父类并提供一个虚拟方法来访问它。我只是忘了在这里做。至于另一个问题,你介意看看这个问题,我只是问了更具体的哪些地址:http://stackoverflow.com/questions/9373004/how-to-turn-this-service-locator-pattern- into-true-dependency-injection-pattern – 2012-02-21 06:27:08
所以......这是否意味着当创建对象时,所有的依赖关系应该总是注入到构造函数(属性或其他)中?似乎有必要在实例化对象后在对象中创建它们,并且此模式会禁止该对象。这是一个限制还是我最后的陈述是错误的评估? – 2012-02-21 06:37:30
@Steven:很棒的回答,删除我的。 :) – Arafangion 2012-02-21 06:42:03