8

我有一个类,它有我用 Ninject 连接的依赖项。

public interface IFoo {}

public class MyObject {
    [Inject]
    IFoo myfoo;
}

在实际实现中,我使用属性注入,但为了快速说明,我将在现场注入。据我了解,为了正确注入依赖项,我需要使用而不是新的 MyObject 实例

kernel.Get<MyObject>()

然而,我遇到的事情是 MyObject 只会在类库的上下文中使用。目的是让最终应用程序创建自己的模块并将其传递给内核实例以进行水合。鉴于此,将 Ninject 内核的通用实例呈现到我的类库以便 MyObject (和其他类似情况)的实例可以被水合的最实用的方法是什么?

我的第一个倾向是某种将单例内核内部化的工厂——应用程序本身必须通过加载模块来对其进行水合/初始化。

所以在 RandomService.cs

var myKernel = NinjaFactory.Unleash();
var myobj = myKernel.Get<MyObject>();
myobj.foo();

不过,在我沿着这条路走得太远之前,我需要进行一次健全性检查,以确保我的想法是合理的,或者没有其他明显的东西我遗漏了。我显然是 IoC 的新手,我觉得我掌握了基础知识,但不一定是最好的现实世界使用它的方法。

4

3 回答 3

9

我不确定我是否了解您问题中的所有细节,但据我所知,您在问如何外部化对 Ninject 的依赖。

无需引用任何特定的 DI 容器(Ninject 或其他任何东西)就可以编写对DI 友好的库。这使得图书馆的消费者可以选择他或她喜欢的 DI 容器(或根本不使用容器)。这种方法更受欢迎,因为它提供了更大的自由度。

但是,您应该真正支持构造函数注入而不是属性注入。虽然 Property Injection 看似简单的实现,但实际上很难做到正确。

构造函数注入的一大优点是您不需要在构造函数上放置任何属性,因为它在结构上已经包含了 DI 容器正确连接它所需的所有信息。

于 2010-02-11T08:37:46.483 回答
4

马克的观点绝对是我对此的起始观点(因此是+1)。注意不要忘记关注他的链接

过去,我曾因过早放弃对属性(或字段)的构造函数而感到内疚(我的“借口”是,作为一个基类需要 5 个属性,我不想让所有派生类都承受这些属性的负担。解决方案那就是包装一个类或类层次结构中涉及的 5 个属性,这些属性代表属性所代表的任何底层概念。有点像 Introduce Parameter Object 重构。

关于我发现有用的考虑的一个很好的讨论是http://thinkbeforecoding.com/post/2009/05/15/IOC-container-go-hide(找不到提到它的 SO 帖子和一些围绕它的主题,也许有人将注入一个链接:D)

另一个总结这些观点的博客是Your IoC Container is Showing

http://davybrion.com/blog/2009/11/integrating-your-ioc-container-with-agatha/

于 2010-02-11T09:43:47.587 回答
0

这是一个很好的通用配方,用于在当前程序集中查找所有 ninject 模块:

IKernel _serviceKernel = new StandardKernel();

Assembly myAssembly = this.GetType().Assembly;

IEnumerable<Type> ninjectModuleTypes = 
     myAssembly.GetTypes().Where(type => type.BaseType == typeof(NinjectModule));

foreach (Type ninjectModuleType in ninjectModuleTypes)
{
    NinjectModule mod = (NinjectModule)Activator.CreateInstance(ninjectModuleType);
    _serviceKernel.Load(mod);
}
于 2012-08-23T20:06:33.487 回答