我正在努力改进 IoC、DI 和 OOD,以获得更好的可测试性和更松散的耦合。
因此,当我们设计大量使用 IoC 和 DI 的类时,我们最终可能会得到具有多个依赖项的类
class Processor
{
private IService1 m_Service1;
private IService2 m_Service2;
private IService3 m_Service3;
//approach 1
public Processor(IService1 service1, IService2 service2, IService3 service3)
{
m_Service1 = service1;
m_Service2 = service2;
m_Service3 = service3;
}
//approach 2
public Processor(IContainer container)
{
m_Service1 = container.Resolve<IService1>();
m_Service2 = container.Resolve<IService2>();
m_Service3 = container.Resolve<IService3>();
}
//approach 3
public delegate Processor Factory();
}
我在想这里通常的方法应该是什么。我们可以为构造函数保留 3 个参数,但是如果我们使用 autofac(例如)构建应用程序,除了解析来自某些容器实例的类型之外,它很可能很少被使用,例如
Processor proc = new Processor(
container.Resolve<IService1>(),
container.Resolve<IService2>(),
container.Resolve<IService3>());
所以我认为当我们依赖容器中的多种类型时,方法 2 可能更好。无论如何,我们必须在某处添加对 autofac 的引用,所以现在有什么理由不这样做吗?
Autofac 还提供了委托(delegate)工厂方法的方法
http://code.google.com/p/autofac/wiki/DelegateFactories
var processorFactory = container.Resolve<Processor.Factory>();
Processor processor = processorFactory.Invoke();
所以我们也有方法 3 - 我们不会使用构造函数来创建我们的类实例,而是我们将从容器调用已解析的委托(delegate),它会为我们解析依赖关系。
由于我对 IoC 还很陌生,所以很难说什么时候应该使用 1、2、3。它们各有优缺点。
我认为一般来说,如果类具有 1 个依赖项,我们可能总是可以使用方法 1..除此之外,我真的不确定该选择什么以及何时选择。
更新 我已经阅读了有关服务定位器反模式的内容,但我想出了第 4 种(或真正的第 3 种方法)
它接近 ServiceLocator 除了它不是,我们传递一个看起来像这样的对象
public class ServiceLocatorObject
{
private IService1 m_Service1;
private IService2 m_Service2;
private IService3 m_Service3;
public IService1 Service1 {get {return m_Service1;}}
public IService2 Service2 {get {return m_Service2;}}
public IService3 Service3 {get {return m_Service3;}}
public ServiceLocatorObject(IService1 service1, IService2 service2, IService3 service3)
{
m_Service1 = service1;
m_Service2 = service2;
m_Service3 = service3;
}
}
现在我们创建
//approach 4
public Processor(ServiceLocatorObject servicesToUse)
{
m_Services = servicesToUse;
}
现在我们已经将我们的类与服务实现分离,并且它清楚它需要什么真正的依赖关系(如果我们假设传递的对象上的所有可用服务都是必需的),因为我们没有传递一个可以包含 100 个实现的容器。如果我们的应用程序中的某个其他类可能需要这 3 个服务组合,则该对象甚至可以重用。所以我们使用的是构造函数 DI 而不是 ServiceLocator 模式。接口(interface)清晰且没有依赖项过载,新类可能是一个很好的重用候选者。
你对这个有什么看法?
最佳答案
如今,服务定位模式通常被认为是一种反模式(使用 container.Resolve 并注入(inject)容器)。
在我自己为这个概念苦苦挣扎并试图决定我是喜欢它还是讨厌它之后,我个人意识到我同意服务位置是一种反模式 - 因为它混淆了存在的相互依赖关系是 OOP 的核心概念。
阅读这里: http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx
我实际上喜欢在选项 1 中,Process 清楚地表达了它对它列出的每个服务的依赖性,这些服务是构造函数中的参数。它使依赖关系非常明显......而且我认为它有助于促进良好的设计。
只是说 Processor takes an IContainer 并不能告诉我们太多...因此您需要更仔细地查看以确定相互依赖性。
关于c# - OOD 使用 IoC 容器 - 如何构造依赖对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7048465/