Our WhatIs site asked me to help with a definition of IoC and DI. I've always disliked the terms, especially IoC, because it just seems so esoteric. I mean, what is inverted? And what exactly does 'control' mean? Surely better words could be used. Dependency injection isn't that bad, but how does it relate to IoT? Anyways, I shot this quick definition over the the WhatIs team. My hope was that it got the point across without being overly technical, while at the same time, it would apply to both Java based environments and people doing SOA.
I'd love to hear some thoughts on what's here. Is there anything you consider misleading or wrong? Could you simplify the definition? Let me know in the comments, or ping me on Twitter: @potemcam
The best code is small, modular code, because it is easy to write, and it's easy to debug. Most big applications are simply a bunch of small, modular pieces that come together at runtime. However, there are probably a set of commons services that are shared across many of these modular little pieces. Each piece might need a database connection, or perhaps a reference to a language bundle that helps internationalize the user interface. Simply speaking, many parts of an application will have dependencies on external services or resources.
Now traditionally, an application that needs a given resource will create it, or instantiate it, or initialize it, all of which are different terms for essentially doing the same thing. But in a big application, a resource needed by a given module has likely already been initialized and created and is running within the application. So to make life simpler, various frameworks and programming languages have created ways for modules of code to sidestep the process of instantiating a given resource, and instead just have the application runtime hand over the instance of the resource that is already running, or a connection to a service that has already been made. If an instance isn't already running, the framework will create one for the application and hand it off. In fact, the process has got so fancy that a module of code can actually ask the runtime to customize the resource they get back according to various properties provided. It's a very elegant way to pass existing references to objects or services or resources to the various modules in an application that needs it.
Since the application runtime is providing resources to a module of code, rather than the module of code instantiating the resource itself, we refer to this process as an Inversion of Control. Control of resources and other external dependencies is being relinquished by the code module, and control is instead being given to the runtime framework. And what is the runtime framework doing? Well, it's providing a resource to the code module that it needs. Basically, it's injecting a needed resource that the given code module requires, thus the name dependency injection.
So why is dependency injection so popular? Well, it relieves various code modules from the task of instantiating references to services and resources. This can be helpful, especially if resource configurations ever change. By allowing the framework to do the resource creation, configuration data is centralized, and changes and updates to how a resource or service is created can occur in one, single place.
Another commonly cited benefit of dependency injection is the fact that injected resources can be customized through XML files which are external to the source code. This means tweaks and changes can be applied without recompiling the entire codebase. However, the use of code based annotations is making this a less universal truth than it has been in the past, as changes to annotations do require a recompile.
Of course, not everybody loves IoT and DI. Sometimes it can make troubleshooting more difficult, as a great deal of code is pushed into a mystery box that creates resources and hands them out across the application. Debugging code when all of the objects that are misbehaving are knee deep in a complicated framework that is provided by a third-party vendor can be very frustrating and time consuming.
In the Java ecosystem, Spring is the most famous of all of the IoT and DI engines, with Google Guice likely coming in second. However, DI and IoT have become such pervasive concepts that in the Java world, DI and IoT are not a standard part of the ecosystem, injected into the Java EE platform through JSR-299: Contexts and Dependency Injection.
Add your thoughts in the comment section, or ping me with something on Twitter: @potemcam