Remote controls are fantastic. The ability to stand over here and control something over there is like magic. Since the first remote controls, which only controlled a single device, were made we’ve extended the idea of the remote control quite a bit. Your remote for your TV can control your Blu-Ray player. You can buy a remote control from Logitech that can be programmed to turn on your TV, set the sound on your stereo, and dim the lights in your TV room….all at the press of one button. You can buy a keychain remote control that turns off all the TVs in a restaurant or bar. In the movies, Adam Sandler made a movie where he found a remote control that controls the whole universe.
The magic of remote controls is in the gap between the controller and the thing controlled. There isn’t a wire. They are not wired together. They are loosely coupled.
We have a good habit of loosely coupling the top side of our code. Anybody can call one of our methods. They aren’t hard wired for only one consumer.
However, on the underside of our code, we fail to couple loosely. We create new instances of database connections and proxy classes. We use Static methods to get resources and get information from the server context. Each time we do this, we break the magic of the remote control. These tight couplings prevent us from changing the implementation of our dependencies (the database connections, proxy classes, and resource systems).
The Dependency Injection Principle protects us from our urges to tightly couple to our dependencies. It states:
1. High Level Modules Should Not Depend Upon Low Level Modules. Both Should Depend Upon Abstractions.
2. Abstractions Should Not Depend Upon Details. Details Should Depend Upon Abstractions.
Frequently, Dependency Injection is implemented by using the constructor. In our classes constructor, we pass in references to the database connection or service proxy. This provides the loose coupling in one easy step. Using a IOC container, like Autofac or StructureMap then automates constructing the object by providing a central point where we can define all those dependencies and compose them into objects.
If you’d like to know more, read the excellent Uncle Bob article.