在这个AutoFac“最佳实践”页面(http://code.google.com/p/autofac/wiki/BestPractices)上,他们说:
不要传递容器,让组件访问容器,或将其存储在公共静态属性中,或使Resolve()等函数在全局“IoC”类上可用,这违背了使用依赖注入的目的。这种设计与服务定位器模式有更多的共同之处。如果组件依赖于容器,请查看它们如何使用容器检索服务,并将这些服务添加到组件的(注入依赖项)构造函数参数中。
那么,让一个组件“动态”实例化另一个组件的更好方法是什么呢?他们的第二段没有涵盖“可能”需要创建的组件将取决于系统状态的情况。或者当组件A需要创建X个组件B时。
发布于 2009-08-01 10:25:30
要抽象出另一个组件的实例化,您可以使用工厂模式:
public interface IComponentBFactory
{
IComponentB CreateComponentB();
}
public class ComponentA : IComponentA
{
private IComponentBFactory _componentBFactory;
public ComponentA(IComponentBFactory componentBFactory)
{
_componentBFactory = componentBFactory;
}
public void Foo()
{
var componentB = _componentBFactory.CreateComponentB();
...
}
}
然后,可以向IoC容器注册该实现。
容器是组装对象图的一种方式,但它肯定不是唯一的方式。这是一个实现细节。保持对象不受这种知识的影响,可以将它们与基础设施问题解耦。它还使他们不必知道要解析哪个版本的依赖项。
发布于 2009-07-31 21:27:30
服务定位器模式更难测试,也更难控制依赖关系,这可能会导致系统中比您真正想要的耦合更多。
如果你真的想要像延迟实例化这样的东西,你仍然可以选择Service Locator风格(它不会立即杀死你,如果你坚持容器的接口,用一些模拟框架测试也不是太难)。但请记住,实例化一个在构造函数中不做太多(或任何事情)的类是非常便宜的。
我所知道的容器(目前为止不是autofac )将允许您根据系统的状态修改应该注入到哪个实例中的依赖项,这样即使是这些决定也可以外部化到容器的配置中。
这可以为您提供很大的灵活性,而无需根据您在使用依赖项的实例中访问的某些状态实现与容器的交互。
发布于 2009-08-01 01:08:29
IoC负责确定给定对象应该使用哪个版本的依赖项。这对于诸如创建实现接口的对象链以及对该接口具有依赖性(类似于命令链或装饰器模式)之类的事情很有用。
通过传递容器,您将把责任放在单个对象上,以获得适当的依赖关系,因此它必须知道如何。对于典型的IoC用法,对象只需要声明它有一个依赖项,而不需要考虑在该依赖项的多个可用实现之间进行选择。
https://stackoverflow.com/questions/1214944
复制相似问题