We are talking with Mark Seemann, co-author of the book Dependency Injection Principles, Practices, and Patterns. Mark has been a speaker at IT Days 2018 where his presentation: Human Code was voted as the best one. He will be a speaker @ The Developers, 23rd May, Cluj-Napoca, where he will talk about Asynchronous Injection.
You start your book with an interested analogy between a power socket, sauce béarnaise and Dependency Injection. What is the link between them?
Mark Seemann: Both are analogies. They're two different ways to look at Dependency Injection, but while both analogies do, I hope, help to explain Dependency Injection, there's no further link between power sockets and sauce Bèarnaise.
The power socket analogy illustrates polymorphism and various design patterns that follow from that. You can think of a socket as an interface. Any plug that fits the socket will work, and will enable electrical current to flow. Different sockets (e.g. US sockets vs. European sockets) correspond to different interfaces. Adapters exist, just like the Adapter design pattern enables you to make one type of object look like another type.
The sauce Bèarnaise analogy is only that it can be a bit tricky to learn, but once you get the hang of it, it's easy and should be foundational. In fact, sauce Hollandaise would be a better analogy, since that's the base sauce from which you make sauce Bèarnaise, and several other sauces, but I chose to use sauce Bèarnaise instead, because it's more well-known. I didn't expect the general reader to know what a sauce Hollandaise is.
Is Dependency Injection the same as Inversion of Control?
Mark Seemann: In my opinion, it's not, and I believe that I've formed that opinion from the work of Martin Fowler. Dependency Injection is a form of Inversion of Control, but Inversion of Control is a much broader concept that also includes the use of application frameworks.
This distinction is, however, probably a lost battle. Most people don't make the distinction and use the terms interchangeably. I still prefer the term Dependency Injection, though, unless I explicitly talk about the broader concept.
What design patterns do you recommend being used in relation with Dependency Injection? What about anti-patterns?
Mark Seemann: The most universally useful design patterns seem to me to be Composite, Null Object, Decorator, Chain of Responsibility, and Visitor. Dependency Injection is essentially just another name for the Strategy pattern, but comes with some specific patterns for how to compose the Strategy with its consumers. The most useful pattern here is Constructor Injection.
Another essential Dependency Injection pattern is the Composition Root. Compose an application's entire object graph at the entry point of the application.
On the anti-pattern side, on the other hand, you find the Service Locator anti-pattern. Unfortunately, this is often what people start with, and many people still think that this is the way one's supposed to do Dependency Injection.
Ambient Context is also best avoided.
I don't particularly consider the use of a DI Container to be an anti-pattern, but many people believe that Dependency Injection requires a DI Container, and that's a mindset that easily leads to the Service Locator anti-pattern, so I always recommend that unless you know what you're doing, don't use a DI Container.
At what should developers pay attention when reviewing an existing DI implementation?
Mark Seemann: The first thing I look for is the presence of Service Locator. I also look for whether or not a DI Container is part of the code base.
It usually also pays to identify the dependency graph of the code base. Which parts of the code base depends on other parts? People usually divide their code bases into various libraries - although they often call them layers. These libraries will typically link to each other in a graph. It pays to understand what that graph looks like. You may have to draw it out on a piece of paper, but although 'dependency graph analysis' sounds academic and abstract, it's easy and usually done in a matter of minutes.
I've seen many a code base where the dependencies go the wrong way. This is easy to identify with a dependency graph.
What should participants expect from your presentation at The Developers 2019 conference
Mark Seemann: To learn something new