Dependency Injection (DI)
The term dependency injection means injecting a dependency for a class from outside.
This design pattern refers to hiding the information about object creation, from
the class where it is used. In simple words if Class A is dependent on Class B for
some task, then Class A is not responsible for creating Class B, rather it is created
outside and injected by the constructor / Setter for Class A by an out side factory/controller
/ container. The Factory/controller/container is the place where the object B is
created.
Different Approaches for DI
- Abstract factory and Factory method are great patterns to achieve DI but they have
some drawbacks. The creation options are hard coded and so not flexible. Also when
a new implementation class is added, we need to change the factories too. So it
is not extensible. In this case all the dependency objects are known at compile
time. So it is not possible to do something in runtime. It is not possible to reuse
the factories.
- Use a controller to dynamically load classes using a particular interface during
start up of the application using .NET reflection. Then this controller is responsible
for getting instances of the classes when needed. But again it is not reusable.
- Use a Dependency Injection container to watch an application and inject dependencies
when ever needed. This can be achieved by some dependency Injection Frameworks like
Spring.NET. This is reusable, easily extensible and flexible. Also it is very easy
to do unit testing with Mock Objects (These are the objects which imitate the real
object.) The Spring.NET uses an XML file for declaring the dependencies. So it depends
on the application need to choose which approach to use.
Example using Spring.NET
The xml configuration file looks some thing like this.
<?xml
version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup
name="spring">
<section
name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section
name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>
<spring>
<context>
<resource
uri="config://spring/objects"/>
</context>
<objects
xmlns="http://www.springframework.net">
<object
name="ClassA"
type="MyExamples.ClassA,
MyExamples">
<!--
using setter injection... -->
<property
name="DependencyClass" ref="ClassB"/>
</object>
<object
name="ClassB" type="MyExamples.ClassB, MyExamples">
</object>
</objects>
</spring>
</configuration>
In the application we must add “
using Spring.Context”.
Then get the context to create objects as below.
IApplicationContext context = ContextRegistry.GetContext();
IDependencyClass myClassB =(
IDependencyClass) context.GetObject(“ClassB”);
Some DI Containers
- Unity DI Container: Unity is a lightweight (only need to include 2 assemblies totalling
about 100K). Get it from Codeplex: http://www.codeplex.com/unity ) extensible dependency
injection container. It addresses the issues faced by developers engaged in component-based
software engineering. Modern business applications consist of custom business objects
and components that perform specific or generic tasks within the application, in
addition to components that individually address cross cutting concerns such as
logging, authentication, authorization, caching, and exception handling. The key
to successfully building such applications is to achieve a decoupled or very loosely
coupled design. Loosely coupled applications are more flexible and easier to maintain.
They are also easier to test during development.
- Spring.NET : We have already discussed it.( Spring.net)
- Autofac (Autofac): A .NET IoC container written in C#. Focus on programmatic configuration
with builder syntax. Zero intrusion into existing code. Create components using
reflection or with lambda expressions for unlimited flexibility. Managed disposal
of any IDisposable components created by the container within a defined scope.
References
- http://martinfowler.com/articles/injection.html
- http://msdn.microsoft.com/en-us/magazine/cc163739.aspx
- http://www.codeproject.com/KB/architecture/DependencyInjection-1.aspx