【问题标题】:NInject: Where do you keep your reference to the Kernel?NInject:你把你对内核的引用保存在哪里?
【发布时间】:2010-10-10 02:33:18
【问题描述】:

我在一个新的 Web 应用程序上使用 NInject,有两件事我不清楚:

  1. 我不需要保留对内核的引用(会话/应用变量)以确保 GC 不会收集我的所有实例吗?例如,如果我指定 .Using() 然后收集 Kernel 对象,我的所有“单例”不也收集了吗?

  2. 如果我确实需要保留对 Kernel 对象的引用,我如何允许传递给 WithArguments() 的参数发生变化,或者这是不可能的。

【问题讨论】:

    标签: c# dependency-injection inversion-of-control ioc-container ninject


    【解决方案1】:

    这是开始使用 IoC 容器时的常见陷阱。见this related question

    简而言之:

    • 传递容器是一种不好的做法(去过那里,做过那个,真的很痛)
    • 如果确实需要直接调用容器,首先考虑抽象为注入工厂,然后作为最后一个资源考虑使用容器的静态网关

    【讨论】:

    • 我同意我不想传递容器,但我可以将它存储在 Application 变量中吗?我的问题是每次我执行 new StandardKernel(new CustomModule()) 时都会得到所有内容的新实例。
    • 每个应用只需要一个 StandardKernel。如果您需要加载多个模块,只需调用 kernel.Load(new MyModule()); kernel.Load(new AnotherModule());等
    • 好的,这是有道理的。我需要做的是每次我要求一个类型时更改 WithArguments() 中的参数......有没有办法做到这一点?最终我要做的是实现一个 OnePerSessionBehavior,我希望绑定为每个会话注入当前参数。
    • 这完全是另一个问题...专门针对该问题发布一个新问题。
    【解决方案2】:

    确实,您不想绕过内核。通常,在 Web 应用程序中,我将内核存储在 HttpApplication 的静态属性中。如果您需要对内核的引用,您只需公开一个 IKernel 类型的依赖项(通过构造函数参数或属性),Ninject 将为您提供对激活该类型的内核的引用。

    如果您在绑定上使用 WithArguments(),它们将用于所有激活。如果您使用 IParameters,它们将仅用于该激活。 (但是,如果您正在激活的服务具有像 Singleton 这样的可重用行为,即使您传递不同的 IParameters,它也不会被重新激活。)

    【讨论】:

    • 这听起来正是我想要的......你能为此发布一些代码吗?
    • @Nate:不完全相关,但您在 CommonServiceLocator 适配器上有任何 ETA 吗?我看到 ninject2 的实验分支上有一个适配器...
    【解决方案3】:

    Mark Seeman --Manning Dependency Injection的作者建议使用好莱坞原则不要打电话给我们(IOC框架),我们会打电话给你……..IOC容器应该放在应用程序的组合根.. 它需要根据请求实例化.. 就像提到的那样

    .. 对于 Web 应用程序,组合根是 Global.asax 文件,您可以在其中使用覆盖启动事件,并且您可以绑定您的 Ninject 来解析组件

    【讨论】:

    • -1,主要是因为答案的措辞如此模糊和模糊。此外,说“它需要根据要求[被]实例化”的部分实际上可以表示任何内容,并且作为指南根本没有帮助。话虽如此,我肯定会支持关于“好莱坞原则”的说法,而组合根是唯一应该直接从 DI 容器中检索的东西。
    • 这个答案没有帮助,因为它只是重复链接的内容。你还没有说Composition Root应该是什么,所以你可以把'IOC Container'这个词划掉并写'Composition Root',这是同一个问题......
    猜你喜欢
    • 2011-03-18
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 2012-10-14
    • 2011-02-22
    • 2010-09-11
    • 2013-07-01
    • 1970-01-01
    相关资源
    最近更新 更多