Dependency injection (DI) in computer programming refers to the process of supplying an external dependency to a software component. Without the concept of dependency injection, a consumer who needs a particular service in order to accomplish a certain task would be responsible for handling the life-cycle (instantiating, opening and closing streams, disposing, etc.) of that service. Using the concept of dependency injection, however, the life-cycle of a service is handled by a dependency provider (typically a container) rather than the consumer. The consumer would thus only need a reference to an implementation of the service that it needed in order to accomplish the necessary task.
As the provider component is responsible for initializing and setup of dependencies, this approach helps in the reduction of boilerplate code in the application objects. It also offers configuration flexibility because alternative implementations of a given service can be used without recompiling code. This feature is very useful in unit testing because of the ease of injecting Mock objects of the service being tested in the config file.
The following are the two main forms of dependency injection:
· Constructor injection: Injects your dependencies in a constructor. The parameters of the object's constructor method are used to express dependencies and to the builder inject it with its dependencies.
e.g. In CAB the InjectionConstructor attribute is used for constructor injection.
[InjectionConstructor]
public ViewUtility([ServiceDependency] MyService service, [CreateNew] ViewModel viewmodel)
The code sample creates a new instance of ViewModel and resolves the ServiceDependecy while creating a new instance of the ViewUtility object via the AddNew method.
· Property/ Setter injection: The dependencies are expressed through setter properties that the builder uses to pass the dependencies to it during object initialization.
E.g. CAB uses the ServiceDependecy attribute to inject property dependencies.
private WorkItem rootWorkItem;
[ServiceDependency]
public WorkItem RootWorkItem
{
set { rootWorkItem = value; }
}
This tells the CAB framework that when it is loading this module it should look for an appropriate WorkItem to ‘inject’ into this setter.
The Dependency Injection pattern can be implemented in several ways. The Unity Application Block (Unity) provides a container that can be used for dependency injection. The Unity Application Block (Unity) is a lightweight, extensible dependency injection container that supports constructor injection, property injection, and method call injection.
The Unity Application Block was designed to achieve the following goals:
· Promote the principles of modular design through aggressive decoupling.
· Raise awareness of the need to maximize testability when designing applications.
· Provide a fast and lightweight dependency injection container mechanism for creating new object instances and managing existing object instances.
· Expose a compact and intuitive API for developers to work with the container.
· Support a wide range of code languages, with method overrides that accept generic parameters where the language supports these.
· Implement attribute-driven injection for constructors, property setters, and methods of target objects.
· Provide extensibility through custom and third-party container extensions.
· Provide the performance required in enterprise-level Line of Business (LOB) applications.
In the upcoming posts on Unity Application block, we’ll see how to use Unity as a dependency injection container in our applications and the benefits it offers.
No comments:
Post a Comment