Design – Should Dependency Injection or Static Factories Be Used?

dependenciesdependency-injectiondesign

When designing a system I am often faced with the problem of having a bunch of modules (logging, database acces, etc) being used by the other modules. The question is, how do I go about providing these components to other components. Two answers seem possible dependency injection or using the factory pattern. However both seem wrong:

  • Factories make testing a pain and don't allow easy swapping of implementations. They also don't make dependencies apparent (e.g. you're examining a method, oblivious to the fact that it calls a method that calls a method that calls a method that uses a database).
  • Dependecy injection massively swells constructor argument lists and it smears some aspects all over your code. Typical situation is where constructors of more than half classes look like this (....., LoggingProvider l, DbSessionProvider db, ExceptionFactory d, UserSession sess, Descriptions d)

Here's a typical situation I have a problem with:
I have exception classes, which use error descriptions loaded from the database, using a query which has parameter of user language setting, which is in user session object. So to create a new Exception I need a description, which requires a database session and the user session. So I'm doomed to dragging all these objects across all my methods just in case I might need to throw an exception.

How do I tackle such a problem??

Best Answer

Use dependency injection, but whenever your constructor argument lists become too big, refactor it using a Facade Service. The idea is to group some of the constructor arguments together, introducing a new abstraction.

For example, you could introduce a new type SessionEnvironment encapsulating a DBSessionProvider, the UserSession and the loaded Descriptions. To know which abstractions make sense most, however, one has to know the details of your program.

A similar question was already asked here on SO.