DI容器是否需要自己实例化对象才能使用构造函数注入?

时间:2014-10-08 15:53:21

标签: c# dependency-injection ioc-container

或者不是自己创建对象,而是以某种方式拦截挂钩对象创建(例如,由MVC框架实例化的Controller)并传入任何内容他们需要依赖?

我知道在创建对象时需要做某事才能使用构造函数注入,但我不清楚容器是否需要进行创建,或者它们是否以某种方式拦截了对象的创造。

无论答案是什么,所有DI容器都是这样做的吗?

我意识到这个问题对于大多数熟悉StructureMap,Unity,Ninject等工具的人来说可能是显而易见的......但我是他们的新手,并意识到我并不知道他们是如何工作的。我在互联网上搜索过,找不到合适的答案。

2 个答案:

答案 0 :(得分:3)

在我使用过的所有DI / IoC容器中,容器都会自行创建。您将找不到使用new Something(dependency1, dependency2)的任何生产代码...相反,您将隐式或明确地要求容器提供“Something的实例”(可能是其他内容的依赖关系) 。然后容器根据它的配置方式(以及Something的注释方式)重新使用Something的实例。

的地方经常显式调用构造函数是在Something的测试中,此时容器可能根本不存在 - 或者你可能有一个特定于测试的配置它允许您以库存方式询问某些依赖项,并可能以特定于测试的方式提供其他依赖项。 (在某些情况下,你仍然不需要显式调用构造函数...如果你有容器的测试配置,例如对所有东西使用假存储,那么你可能仍然需要要求在您的测试中使用Something的实例。)

答案 1 :(得分:3)

至少有三种不同的方法。

最常见的是当容器单独调用构造函数时,使用某种反射和递归方法来解析参数。

但有时候,现有实例(手动创建)会传递给容器构建它们,这是为了满足这些依赖关系,除了构造函数注入之外可以满足这些依赖关系(否则这里的意思是“with property”)注射”)。不过,这可能不是你所要求的。

 var foo = new Foo( new Bar() );
 container.BuildUp( foo );  

经常使用的最后一种方法是在容器中注册工厂方法。容器在这种方法中不会调用构造函数,而是调用工厂方法,并且方法是手动实现的,这意味着工厂的代码直接调用构造函数:

 container.RegisterType<IFoo>( 
    new InjectionFactory( c => new Foo( new Bar() ) ) );