I am trying to get better with IoC,DI and OOD for better testability and looser coupling.
So when we design classes with heavy use of IoC and DI we can endup with classes with multiple dependencies for example
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();
}
Im thinking what should be the usual approach here. We can leave constructor with 3 parameters, but if we are building app using autofac (for example) most likely it will rarely be used other than by resolving types from some container instance like
Processor proc = new Processor(
container.Resolve<IService1>(),
container.Resolve<IService2>(),
container.Resolve<IService3>());
so I am thinking maybe approach 2 is better, when we depend on multiple types from container. Anyway we will have to add reference to autofac somewhere, so any reasons not to do it now?
Autofac also provides delegate factory method approach
http://code.google.com/p/autofac/wiki/DelegateFactories
var processorFactory = container.Resolve<Processor.Factory>();
Processor processor = processorFactory.Invoke();
So we have also approach 3 - we will not use constructors to create our class instances, instead we will be calling resolved delegate from container and it will resolve dependencies for us.
Since im fairly new to IoC its hard to say when we should use 1,2,3. They have advantages and disadvantages.
I think generally if class has 1 dependency we can probably always use approach 1.. other than that I am really not sure what to choose and when.
UPDATE i have read about service locator anti pattern but Ive come up with 4th (or true 3rd approach)
its close to ServiceLocator except its not, we pass an object that looks like this
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;
}
}
And now we create
//approach 4
public Processor(ServiceLocatorObject servicesToUse)
{
m_Services = servicesToUse;
}
Now we have decoupled our class from service implementations and its clear what real dependencies it needs (if we assume all services availabe on passed object are required) because we aren't passing a container that can contain 100 implementations. And that object can be even reused if that 3 service combination might be required in some another class in our application. So we are using constructor DI not ServiceLocator pattern. interface is clear and not overloaded with dependencies, new class might be a good reuse candidate.
What would you say about this one?