为什么不通过你的IoC容器?

Wil*_*rth 18 dependency-injection inversion-of-control

在这个AutoFac"最佳实践"页面(http://code.google.com/p/autofac/wiki/BestPractices)上,他们说:

不要传递容器给组件访问容器,或将其存储在公共静态属性中,或者在全局"IoC"类上使用Resolve()这样的函数会破坏使用依赖注入的目的.这种设计与服务定位器模式有更多共同之处.如果组件依赖于容器,请查看它们如何使用容器来检索服务,并将这些服务添加到组件(依赖注入)构造函数参数中.

那么,让一个组件"动态"实例化另一个组件会有什么更好的方法呢?他们的第二段不包括"可能"需要创建的组件将取决于系统状态的情况.或者当组件A需要创建X个组件B时.

Bry*_*tts 19

要抽象出另一个组件的实例化,可以使用Factory模式:

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();

        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

然后可以在IoC容器中注册实现.

容器是组装对象图的一种方式,但它肯定不是唯一的方法.这是一个实现细节.保持对象不受这些知识的影响将它们与基础设施问题分离开来.它还使他们不必知道要解析哪个版本的依赖项.


Nic*_*rdt 10

Autofac实际上对于这种情况实际上有一些特殊功能 - 详细信息在wiki上:http://code.google.com/p/autofac/wiki/DelegateFactories.

本质上,如果A需要创建B的多个实例,A可以依赖于Func <B>,并且Autofac将生成一个从容器中返回新B的实现.

上面的其他建议当然是有效的 - Autofac的方法有几点不同:

  • 它避免了对大量工厂接口的需求
  • B(工厂的产品)仍然​​可以具有容器注入的依赖项

希望这可以帮助!

缺口