【问题标题】:Is Kernel.Get<T>() threadsafe + good pattern to share the kernel among components是 Kernel.Get<T>() 线程安全 + 在组件之间共享内核的好模式
【发布时间】:2011-06-14 02:55:37
【问题描述】:

Kernel.Get() 线程安全吗?我的目标是在我的所有组件之间共享我的内核实例,并且它们都可以很好地在不同线程上同时调用 Kernel.Get()。

Kernel.Get() 线程安全吗?

在位于不同 dll 中的所有应用程序组件之间共享应用程序内核的最佳模式是什么?如果有意义的话,我不希望将工厂的实例传递给我的应用程序的每个组件。

【问题讨论】:

    标签: ninject ninject-2


    【解决方案1】:

    Get 是线程安全的,但创建新的内核实例 (ctor) 目前不是线程安全的。

    一般来说,您应该尽量将您对内核的访问降至最低。到处访问内核形式是一个非常糟糕的设计,并且会使您的代码的可重用性大大降低。见Service Locator Antipattern

    您访问内核的唯一情况应该是:

    • 在应用程序的复合根目录中(例如 Program.Main、App.xaml、MVC 控制器创建)
    • 如果在创建复合根时不知道需要多少个实例,则在工厂内部
    • 如果在创建复合根时不知道需要哪个实现,则在工厂内部
    • 如果您因内存/资源限制而需要延迟创建组件,则在工厂内。

    在所有情况下,将对内核的访问限制为复合根,并将工厂(类或Func&lt;T&gt;)注入到您需要在运行时创建对象的类。让这些工厂访问内核的最佳方法仍然是构造函数注入,即使您不喜欢这样做。或者使用Func&lt;T&gt; (Does Ninject support Func (auto generated factory)?)。

    【讨论】:

    • 感谢您的回答。我的代码库由几个代理/组件组成,我希望我的每个代理都有一个独立的服务实例。这是否也适用于访问传递工厂内的 kernel.get 方法?有没有更好的方法让您的应用程序的许多组件通过 IoC 获取服务的独立实例?另外,您能否详细说明一下 Func 方法?也许是一个如何使用它的代码示例以及附加值是什么?
    • @RemoGloor:你能解释一下kernel如何注入工厂吗?我很困惑,因为我们需要内核来解决依赖关系,但是内核是如何自己注入的呢?
    【解决方案2】:

    是的,它是线程安全的;我工作的主要应用程序有一个服务于大型 SAAS 应用程序的内核。所以它被捣碎了,它做得很好。我们还有一个多线程页面生成器测试套件,它在去年秋天暴露了 Ninject 中的一个线程问题,但从那时起已经修复并且一直很好。所以我确定没问题。

    有很多不同的模式来暴露内核。我们使用 ServiceLocator 模式(基本上是容器的静态容器。)

    对于不同的 dll。我们在每个 dll 中都有一个 NinjectModule,它自己绑定,然后应用程序在启动时设置 ServiceLocator 时对 NinjectModules 进行程序集扫描。

    【讨论】:

    • 您能否详细说明“对于不同的 dll。我们在每个 dll 中都有一个 NinjectModule,它执行它自己的绑定,然后应用程序在启动时对 NinjectModules 进行程序集扫描,当它设置 ServiceLocator ."?
    • StandardKernel 有一个加载方法,它采用程序集名称或名称数组。然后,它会扫描每个这些程序集以查找公共 NinjectModule 类。请参阅 github.com/ryber/Ninject-Examples/blob/master/src/… 的测试 AssemblyScanningByFileName
    猜你喜欢
    • 2017-10-02
    • 2015-12-12
    • 1970-01-01
    • 2011-12-16
    • 2015-06-04
    • 1970-01-01
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多