I am familiar with these patterns but still don't know how to handle following situation:
public class CarFactory
{
public CarFactory(Dep1,Dep2,Dep3,Dep4,Dep5,Dep6)
{
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return new Car1(Dep1,Dep2,Dep3);
break;
case B:
return new Car2(Dep4,Dep5,Dep6);
break;
}
}
}
In general the problem is with amount of references that needs to be injected. It will be even worse when there are more cars.
First approach that comes to my mind is to inject Car1 and Car2 in factory constructor but it is against factory approach because factory will return always the same object. The second approach is to inject servicelocator but it's antipattern everywhere. How to solve it?
Edit:
Alternative way 1:
public class CarFactory
{
public CarFactory(IContainer container)
{
_container = container;
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return _container.Resolve<ICar1>();
break;
case B:
return _container.Resolve<ICar2>();
break;
}
}
}
Alternative way 2 (too hard to use because of too many of dependencies in tree):
public class CarFactory
{
public CarFactory()
{
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return new Car1(new Dep1(),new Dep2(new Dep683(),new Dep684()),....)
break;
case B:
return new Car2(new Dep4(),new Dep5(new Dep777(),new Dep684()),....)
break;
}
}
}
Answering your comment about code example with
Composition Root
. You can create following and this is not a Service Locator.and this is how look your
Composition Root
using Unity DI container :I would consider giving the dependencies a good structure so you can utilize something similar to Wiktor's answer, but I would abstract the Car factory itself. Then, you don't use the if..then structure.
I didn't list it, but you can implement multiple types of cars and their corresponding factories now and use DI to inject whatever you need.
First, you have a concrete factory, an IoC container could be an alternative rather than something to help you there.
Then, just refactor the factory to not to expect a full possible parameter list in the factory constructor. This is the primary issue - why are you passing so many parameters if the factory method doesn't need them?
I would rather pass specific parameters to the factory method
By encapsulating the parameter list in a specific class you just make the client provide exactly these parameters that are required for specific factory method invocation.
Edit:
Unfortunately, it was not clear from your post what are these
Dep1
, ... and how you use them.I suggest following approach then that separates the factory provider from actual factory implementation. This approach is known as the Local Factory pattern:
The factory itself doesn't have any implementation, it is here to set the foundation to your domain API, where you want your car instances to be created with this API only.
Then, in the Composition Root (somewhere near the starting point of the app where you configure your actual container), you configure the provider:
Note that this example implementation of the factory's provider uses a delegate but an interface could also be used as a specification for an actual provider.
This implementation is basically #1 from your edited question, however, it doesn't have any particular downsides. The client still calls:
Having a switch case statement inside of a factory is a code smell. Interestingly, you don't seem to be focusing on solving that issue at all.
The best, most DI friendly solution for this scenario is the strategy pattern. It allows your DI container to inject the dependencies into the factory instances where they belong, without cluttering up other classes with those dependencies or resorting to a service locator.
Interfaces
Factories
Strategy
Usage
Note that because there is no switch case statement, you can add additional factories to the strategy without changing the design, and each of those factories can have their own dependencies that are injected by the DI container.
Many DI containers support the notion of named dependencies.
E.g. (Structuremap syntax)
If you use something like a convention, a rule how the name is derived from the concrete car type itself, you have a situation where you don't need to touch the factory anymore when you extend the system.
Using this in a factory is straightforward.
I answered a similar question some time ago. Basically it's all about your choice. You have to choose between verbosity (which gives you more help from a compiler) and automation, which allows you to write less code but is more prone to bugs.
This is my answer supporting verbosity.
And this is also a good answer that supports automation.
EDIT
I believe the approach you consider wrong is actually the best. Truth being said, usually there won't so many dependencies in there. I like this approach because it's very explicit and rarely results in runtime errors.
This one is bad. It's actually a service locator, which is considered an anti-pattern.
Like you wrote, it's not easy to use if mixed with IOC containter. However in some case a similar approach (poor man's DI) can be useful.
All in all, I wouldn't bother having "many" dependencies in your factories. It's a simple, declarative code. It takes seconds to write and can save you hours of struggling with runtime errors.