When designing a software application, a major concern is that the design must be loosely coupled because loose coupling offers greater reusability, maintainability, and testability. Dependency Injection (DI) reduces the coupling between classes and moves the binding of abstraction and concrete implementation out of the dependent class. Dependency Injection enables developers to better manage future code changes and complexity in our software, thus helping us to make our code maintainable. Dependency Injection could be achieved by Construction Injection, Setter Injection, and Interface-based Injection techniques.
The Dependency Injection (DI) Design Pattern
Inversion of Control (IOC) and Dependency Injection (DI) are used to remove dependencies of an application. This makes the system more decoupled and maintainable. Dependency Injection (DI) is a design pattern that demonstrates how to create loosely coupled classes. The Dependency Injection (DI) pattern uses a builder object to initialize objects and provide the required dependencies to the object, meaning that it allows developers to “inject” a dependency from outside the class. There are four ways of achieving the Dependency Injection. Figure 1 explains those.
Figure 1: Types of Dependency Injection
Inversion of Control is a generic term. Rather than having the application call the methods in a framework, the framework calls implementations provided by the application. Dependency Injection is a form of Inversion of control, where implementations are passed into an object through constructors/setters/service lookups, which the object will ‘depend’ on to behave correctly. Dependency Injection frameworks are designed to make use of DI and can define interfaces to make it easy to pass in the implementations.
List of Dependency Injection Frameworks
Following is a list of popular Dependency Injection containers.
Spring.NET is one of the popular open source frameworks for Dependency Injection. Spring.NET supports .NET 4.0, .NET Client Profile 3.5 and 4.0, Silverlight 4.0 and 5.0, and Windows Phone 7.0 and 7.1.
Castle Windsor is a mature Inversion of Control Container available for .NET and Silverlight. The current version is 4.0, released in July 2017. Castle Windsor could be downloaded from GitHub or NuGet. The advantages of using Castle Windsor is that it is completem it understands decorators, and its very well documented.
The Unity Application Block (Unity) is a lightweight, extensible dependency injection container which is relatively more complicated and obtrusive code. Unity uses a container and XML data. It has strong XML support and works with WPF applications. It’s free under the Microsoft public license. Unity addresses the issues faced by developers engaged in component-based software engineering. Unity also includes the Interception container extension, which allows developers to inject exception management, logging, or even your own custom code between the caller and the called.
StructureMap is a Dependency Injection tool for .NET that can be used to improve the architectural qualities of an object-oriented system by reducing the mechanical costs of good design techniques. It’s released under the permissive Apache 2 OSS license. It’s free, and a developer can download, modify, or redistribute StructureMap.
Autofac is an Inversion of Control (IOC) container for Microsoft .NET C#, versions 3.0 and above. Licensed under MIT, it manages the dependencies among classes so that applications stay easy to change as they grow in size and complexity.
An open source, ultra-lightweight, and universal dependency injection framework for .NET, Mono, .NET Compact Framework, and Silverlight. It is licensed under Apache 2. Ninject helps you use the technique of dependency injection to break your applications into loosely coupled, highly-cohesive components, and then glue them back together in a flexible manner.
Advantages of Dependency Injection
Dependency Injection (DI) helps class decoupling. Dependency Injection (DI) and Inversion of Control make it simple for a developer to manage dependencies between objects; that makes it easier fora developer to break coherent functionality off into its own contract. As a result, code become more modularized. It also increases reusability of the code and improves code maintainability and testing.
Downsides of Dependency Injection
Your code can become harder to understand. Dependency Injection (DI) increases code complexity, usually by increasing the number of classes, which is not always beneficial. Generally, the benefit of decoupling makes each task simpler to read and understand, but increases the complexity of orchestrating the more complex tasks.
Dependency Injection (DI) takes a higher learning curve. To understand how a project uses dependency injection, a developer needs to understand both the dependency injection pattern and the specific framework.
Using a Dependency Injection framework, clients are dependent on the configuration data. This becomes an extra task for developers when the application does not need so many custom configuration values.
Dependency Injection continues to grow in popularity within the developer community. Inversion of Control (IOC) talks about who is going to initiate the call, whereas Dependency Injection (DI) talks about how one object acquires dependency on other object through abstraction. If you use Dependency Injection (DI), there are a number of styles to choose between. I would suggest you follow constructor injection.