Val*_*zub 5 c# oop dependency-injection inversion-of-control autofac
我正在尝试使用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();
}
Run Code Online (Sandbox Code Playgroud)
我在想这里应该采用什么方法.我们可以给构造函数留下3个参数,但是如果我们使用autofac构建应用程序(例如),很可能除了从某些容器实例中解析类型之外很少使用它
Processor proc = new Processor(
container.Resolve<IService1>(),
container.Resolve<IService2>(),
container.Resolve<IService3>());
Run Code Online (Sandbox Code Playgroud)
所以当我们依赖容器中的多种类型时,我想也许方法2更好.无论如何,我们将不得不在某处添加autofac的引用,所以任何理由现在都不要这样做?
Autofac还提供委托工厂方法方法
http://code.google.com/p/autofac/wiki/DelegateFactories
var processorFactory = container.Resolve<Processor.Factory>();
Processor processor = processorFactory.Invoke();
Run Code Online (Sandbox Code Playgroud)
所以我们也有方法3 - 我们不会使用构造函数来创建我们的类实例,而是我们将从容器中调用已解析的委托,它将为我们解析依赖关系.
由于我对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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们创造了
//approach 4
public Processor(ServiceLocatorObject servicesToUse)
{
m_Services = servicesToUse;
}
Run Code Online (Sandbox Code Playgroud)
现在我们已经将类与服务实现分离,并清楚它需要什么样的实际依赖项(如果我们假设所有服务都需要传递对象),因为我们没有传递一个可以包含100个实现的容器.如果在我们的应用程序中的某个另一个类中可能需要该服务组合,那么该对象甚至可以被重用.所以我们使用构造函数DI而不是ServiceLocator模式.接口是清晰的,没有依赖的重载,新类可能是一个很好的重用候选者.
你对这个怎么说?
现在,服务位置模式通常被认为是反模式(使用container.Resolve和注入容器).
在我自己努力解决这个概念并试图决定我是喜欢它还是讨厌它之后,我逐渐认识到我同意服务位置是一种反模式 - 因为它模糊了存在的相互依赖性,这是一个核心OOP的概念.
请阅读:http: //blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx
实际上,我认为在选项1中,Process CLEARLY表示它对列出的每个服务的依赖关系是构造函数中的参数.它使依赖性非常明显......而且我认为它有助于促进良好的设计.
只是说处理器需要一个IContainer并没有告诉我们太多...因此你需要仔细看看以确定相互依赖性.
JeffN825给出的答案是正确的,但我想补充一点,你永远不会使用像这样的容器创建一个新的Processor实例:
Processor proc = new Processor(
container.Resolve<IService1>(),
container.Resolve<IService2>(),
container.Resolve<IService3>());
Run Code Online (Sandbox Code Playgroud)
相反,您可以让容器自动连接依赖项并一次解决:
Processor proc = container.Resolve<Processor>();
Run Code Online (Sandbox Code Playgroud)