如何在应用程序中组织DI Framework使用?

时间:2012-02-21 04:43:09

标签: dependency-injection inversion-of-control ninject

编辑:我忘记将内核移动到非泛型父类中,并提供虚拟方法来访问它。我确实意识到下面的例子会产生大量的内核实例。

我刚刚学会了如何在上周进行注射,这就是我目前如何设置注意事项:

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模块类作为Infrastructure命名空间的一部分,以便加载它们。

我无法在这里或Google上找到任何有关如何在项目中实际组织Ninject使用的示例,但这对我来说似乎是正确的,因为它允许我只需要Ninject参考部件。这或多或少是“正确的”方式还是有更好的设计?

1 个答案:

答案 0 :(得分:4)

现在你做的事情有一些问题。

首先让我从明显的C#问题开始:泛型类中的静态类变量是基于T共享的。换句话说,Inject<IUserRepository>Inject<IOrderRepository>将各自获得自己的IKernel实例,这不太可能是您真正想要的,因为您很可能只需要一个IKernel申请的有效期。如果您没有单独的IKernel应用程序,则无法将类型注册为singleton,因为singleton始终在容器级别进行范围设定,而不是在应用程序级别。因此,您最好将类重写为非泛型,并将泛型类型参数移动到方法中:

Inject.New<T>()

第二个问题是涉及依赖注入。在我看来,您正在尝试使用Service Locator anti-pattern,因为您可能在应用程序中明确地调用了Inject.New<T>。 DI容器只应在应用程序的启动路径中引用,并且应该能够构建相关对象的完整对象图。这样,您可以要求容器为您获取根级对象(例如MVC上下文中的Controller),并且应用程序的其余部分将无视任何DI技术的使用。执行此操作时,无需抽象使用容器(就像使用Inject类一样)。

并非所有应用程序或UI技术都允许此BTW。在使用Web窗体应用程序时,我倾向于隐藏我的容器(就像你正在做的那样),因为不可能对Page类,IHttpHandler对象和{{1}进行适当的依赖注入} class。