Dependency Injection Breaks Encapsulation

Let me turn the question around - can you have Dependency Injection without Inversion of Control? Can you have Inversion of Control without Dependency Injection? What is the difference between DI and IoC? Until someone can come up with a description that these two concepts are completely different and not interchangeable I shall stick with my claim that this thread is about DI and not IoC.

But I don’t use constructor arguments in my framework as I don’t need to configure an object an object before I can use it.

Your interpretation of that definition of DI is too tight, in my opinion. I AM passing a dependency (a service) to a client object which then becomes part of the client’s state. The fact that I am passing in the name of a class which has to be instantiated into an object instead of a pre-instantiated object is merely a minor technical detail. The client does not have to find or build the service, it simply executes the “new” function on whatever class name it has been given. Using “new” without any arguments is not the same as “building” an object by supplying a variety of constructor arguments which can vary according to the circumstances.

I do not agree that code is not “more testable” because it is separated. By having code fragmented across several different places you are actually making it more difficult for a human to follow, and code that is easy for a human to understand should take priority.

I do not agree that using DI will always provide benefits, and you will never convince me otherwise. DI was designed to be used in particular circumstances, and I use it where those circumstances appear in my framework. Where those particular circumstances do not exist then there is no benefit in using DI, so where those circumstances do not exist in my framework I do not use DI.

My opinion on this matter has two parts:

  • when used in appropriate circumstances DI does not break encapsulation
  • when used in inappropriate circumstances DI does break encapsulation.

My Controllers are designed to work with one of any number of possible alternative Model objects, so I need to inject the identity of that Model so that the Controller can work…

Where I have a Model which needs to access another Model I know which Model it is as there are no alternatives, no choices, so I don’t need, nor do I use, DI.