Saturday, June 23, 2012

Inversion of Control (IoC) and Dependency Injection (DI)

The Scenario

We have a pretty good idea of what tasks various components of a system must perform but we may want to change the precise way those tasks are carried out by the components at a later time.

The Solution

  • Define interfaces (service contracts) for each component. These interfaces specify the commands and parameters a system must provide to a component that implements a given interface
  • At development time, use the well-defined interfaces to establish the interaction and collaboration between these components
  • At configuration or run time, inject concrete implementations of these interfaces to carry out the actual work

Basic Principles

Inversion of control

Inversion of control is a mechanism by which we can make the higher level modules depend on abstractions rather than concrete implementation of lower level modules.

Dependency injection

Dependency injection is used to reduce the coupling between classes and to move the binding of abstraction and concrete implementation out of the dependent (high level) class. The concrete implementation can be bound to high level class:
  1. By injecting instance(s) of concrete implementation into the high level class constructor
  2. By calling a method on the high level class that takes concrete implementation instance(s) as an argument
  3. By setting a property on the high level class that holds a reference to concrete implementation instance

Implementation Details

Inversion of Control Container (Ioc Container)

  • Use a central repository to register all components that implement the interfaces required to run the system
  • At runtime lookup, by service contract, configured/desired components that implement the functionality required of the system

Dependency Injection

  • Once an appropriate component is identified for each collaborator's interface in the system, create an instance of that component by creating and injecting required parameters into component constructor and/or by setting optional properties of the component
  • Let the system orchestrate the interaction between these concrete instances of the component

IoC and DI Frameworks

There are several prebuilt frameworks available that provide an IoC container as well as Dependency Injection.
  • Castle Windsor and MicroKernel
  • Spring.NET
  • StructureMap
  • Unity
  • Ninject
  • ObjectBuilder