- The Problem: Decoupling
- The Solution for Decoupling: Dependency Injection
- Microsoft's Answer: The Managed Extensibility Framework
- More than Meets the Eye
- Wrapping Up
The Solution for Decoupling: Dependency Injection
Inversion of Control (IoC) is a pattern for decoupled systems, and dependency injection is an implementation of this pattern. (The two terms are often used interchangeably.) When a component is written using an interface, it gives up control of how the interface is implemented. The control is inverted (moved) from the component to an external host of the component. The dependency no longer resides in the control, but instead is injected.
There are many ways to invert the control. One common method is to use constructor injection and pass the implementation into the class when it's created. The travel agency example now would look like this:
public class BookingManager { private IBookTravel _bookingService; public BookingManager(IBookTravel bookingService) { _bookingService = bookingService; } public void DoBooking() { var itinerary = _bookingService.BookVacation(...); } }
The interface is still used, but the dependency no longer exists; it has been injected from somewhere else. This technique makes the class easy to reuse. A test harness can create a test implementation and inject that for unit testing, while the production code will provide a different implementation based on whether the booking happens by phone or via the Internet.
The component no longer has a dependency, but we still have a problem: The component needs to be created somewhere, and the dependency must be injected somehow. Traditional IoC solutions typically use a bootstrapper to configure components explicitly. The bootstrapper component has its own dependencies, but they're isolated to a single place within the application. This is usually a container that can be passed around; it can create classes while passing in the required dependencies, or it can be queried to return an implementation for an interface.