API Design: Don't Force the User to Assemble Components
Jakob Jenkov |
One of consequences of the populary of dependency injection is unfortunately also a sometimes over-religious belief that every dependency should be injected. This is a false belief in my opinion. Especially in the case of dependencies used internally in an API.
Even if only a single class of an API is exposed to the outside world, you may still decide to split up the internal implementation into several smaller classes for various reasons. Let's say that the exposed component A needs both a B, C and D internally to do it's job. Let's again say, that C needs E and F to do its job too. Here is how the dependency hierarchy looks:
A --> B --> C --> E --> F --> D
Let's take a step further, and assert that you will never need a different implementation of either B, C, D, E or F, nor a different configuration of any of these instances. You know that for a fact. In that case there is no reason at all to have A (and C for that matter) assembled via dependency injection, as I have also stated in the text When to use Dependency Injection. You might as well have A instantiate B, C and D internally, and have C instantiate E and F internally. There is no reason to expose B, C, D, E and F to the world.
If you do force the user to assemble the whole hierarchy, the user will have to learn more details of your API than necessary. Even if you have a DI container inject all the instances, looking at the API docs may still confuse the user more than necessary.
Just to make sure you know what I mean, I've included a small code sample of A here:
public class A { protected B b = new B(); protected C c = new C(); protected D d = new D(); }
Tweet | |
Jakob Jenkov |