Always wanted to know how to use Dependency Injection with Delphi? I’ve set up an example for you in which we go from strongly coupled code to beautiful, uncoupled code in a few steps via Dependency Injection and with the help of interfaces.
We’ll start with the following example:
As you can see, there is nothing wrong with the code in principle. It is valid Delphi code and it works. However, there are a few remarks to be made. First of all, the code is strongly coupled; the TWordApp class not only depends on the TLanguageTools class, but you cannot even extend the TLanguageTools class with extra functionality. Even if you would override the TLanguageTools class with, for example, TEnglishLanguageTools, TWordApp simply uses the base class TLanguageTools.
We can do better than that! A first major improvement is to remove the dependency from the constructor Create, and inject it. Injecting a dependency can be done in several ways, via properties, procedures or constructors. In this example, I use the constructor. The code below already has a slightly looser dependency between the two classes:
As you can see in the example, we are still using the TLanguageTools class. However, it is now possible to override this TLanguageTools class, and give this new class to the TWordApp class. And actually, this is the basis of Dependency Injection. Your code is much more loosely coupled and reusable.
By using interfaces, we can go one step further. It is possible to describe the functionality of the TLanguageTools class in different interfaces, and pass this on to the TWordApp class. In this way, we program against abstractions, and not against implementations.
As you can see, the TWordApp class is no longer at all dependent on the TLanguageTools class. As long as we pass on to the constructor an instance with an implementation of the ITranslator interface, the code will just work. We don’t even need the TLanguageTools class anymore.
So, with the help of Dependency Injection and with interfaces, we get nice, decoupled, and well-maintained sourcecode.