Dependency injection containers and factories

141 views
Skip to first unread message

Daniel Karp

unread,
Oct 25, 2013, 10:18:30 AM10/25/13
to clean-code...@googlegroups.com
My understanding has been that dependency injection containers are useful ways to automate dependency injection, but that, essentially, only main should know about the container. This makes a lot of sense--your business logic shouldn't care about how it gets its dependencies.

However, what about factories? Right now, I have an application with a Use Case factory that is a dependency of my Controllers. My use case factory doesn't know about the container--instead, it receives all of the dependencies of the use cases it handles in its constructor, and directly instantiates the use cases, passing the correct dependencies.

This was fine when most of the Use Cases handled by the factory had the same dependencies, but as the application becomes more complex,the number of dependencies increases, and I'm instantiating classes I don't need to construct my Use Case factory. My temptation is to instead pass the dependency injection container into the Use case constructor, so that it can instantiate dependencies on demand via the container.

But that seems like a slippery slope--if I do that, it seems I should just have the container responsible for instantiating the use cases, so that the Factory is essentially a Facade for the container, and if I do  THAT, I start wondering why not pass the container directly into my Controllers as a dependency, rather than the factory.

Is there any point along that slope that makes the most sense to stop?

Daniel Karp

unread,
Oct 25, 2013, 11:04:12 AM10/25/13
to clean-code...@googlegroups.com
A follow up--I talked with one person who suggested that my problem is that my Controllers are doing too much. Rather than having one PostsController, that handles, for example, store, view, update, and delete, I could split it into four separate Controller classes. Then, rather than passing a UseCaseFactory to the Controller, I'd just pass the correct use case to each controller.

I can see how that would make sense--I have one class per use case, one not one class per controller for each use case? But that isn't the way I usually see controllers built, so maybe there is some downside to that that i'm missing. That would also certainly involve some refactoring--luckily I have a test suite I trust. :) 

Any thoughts on that solution? 

Bartosz Borowik

unread,
Oct 25, 2013, 12:37:06 PM10/25/13
to clean-code...@googlegroups.com
However, what about factories? Right now, I have an application with a Use Case factory that is a dependency of my Controllers. My use case factory doesn't know about the container--instead, it receives all of the dependencies of the use cases it handles in its constructor, and directly instantiates the use cases, passing the correct dependencies.

This was fine when most of the Use Cases handled by the factory had the same dependencies, but as the application becomes more complex,the number of dependencies increases, and I'm instantiating classes I don't need to construct my Use Case factory. My temptation is to instead pass the dependency injection container into the Use case constructor, so that it can instantiate dependencies on demand via the container.


As far as I know, most of the inversion of control containers should have a common simple solution for your problem. Instead of injecting into your factory all of the possible dependencies for all the possible use cases the factory creates, you could let the container inject into the factory the actual factory functions. Through these functions you no longer create use cases directly instantiating them in the factory but let the container supply you with them and in such case the container is still the one who is responsible for providing created use cases with all the dependencies they need.

For instance, in a very powerful IOC for C# called Autofac, you could achieve it in the following way: (assumed the types are correctly registered in the container)

public class Flywheel
{
}

public class Engine
{
public Engine(Flywheel flywheel)
{
}
}

public class Undercarriage
{
}

public class Factory
{
public Factory(Func<Engine> engineFactory, Func<Undercarriage> undercarriageFactory)
{
this.engineFactory = engineFactory;
}

Engine createEngine()
{
return engineFactory();
}

Undercarriage createUndercarriage()
{
return undercarriageFactory();
}

private Func<Engine> engineFactory;
private Func<Undercarriage> undercarriageFactory;
}

As you resolve the CarFactory from the IOC it will be provided with necessary factory functions for the Engine and Undercarriage. Through these factory functions you can easily create that parts even not knowing that the Engine needs a Flywheel to be created. A correct instance of Flywheel will be provided by the IOC when it creates the Engine on your call to the factory function.

The same functionality you'll find in Spring and I know of at least one IOC for PHP which can do this too.

Sebastian Gozin

unread,
Oct 25, 2013, 2:40:28 PM10/25/13
to clean-code...@googlegroups.com
This sounds a lot like whet Uncle Bob discussed at https://sites.google.com/site/unclebobconsultingllc/blogs-by-robert-martin/dependency-injection-inversion
It seems quite reasonable to me to hide the generic factory behind  more specific factory.
Reply all
Reply to author
Forward
0 new messages