我希望通过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还提供了委托工厂方法的方式。
http://code.google.com/p/autofac/wiki/DelegateFactories
var processorFactory = container.Resolve<Processor.Factory>();
Processor processor = processorFactory.Invoke();
我们还有第三种方法-不使用构造函数来创建类实例,而是从容器中调用已解决的委托,并且容器将为我们解决依赖关系。
由于我对IoC相当新,很难说我们应该何时使用1、2、3。它们都有优点和缺点。
我认为通常如果类只有一个依赖项,我们可能总是可以使用方法1... 除此之外,我真的不知道该选择什么和何时选择。
更新:我已经阅读了关于服务定位器反模式的信息,但我提出了第四种(或真正的第三种)方法。
它与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模式。接口清晰而没有超载依赖项,新的类可能是一个很好的重用候选项。
ServiceLocatorObject
是做什么的?我无法从提供的示例中确定,因为它没有任何行为? - Mark Seemann