Introduction
This is basically used for developing the loosely coupled components and
provides the pluggable infrastructure. Decoupling (loose coupling) components design can be made by introducing
the interfaces which makes less dependency on the actual implementation and as
a result internal change in the implementation does not affect the upper level components which they actually use.
Loose coupling is considered to be the most appropriate programming approach in
Object Oriented Programming. Loose coupling is nothing but a practice or
approach to make sure the components in a system or a network is dependent to
each other as much least as
possible. It is doing so to reduce the risk that can happen when a change is
made to any of the module or component in a system. Limiting the
interconnections between those will help to isolate the problems if something
goes wrong in any of these components. The trouble shooting and maintenance
will be easy because the one which has the issue will be least connected to
others....
Below is the basic overview copied from the msdn and we will
mainly concentrate how to use it practically.
“The Unity Application Block (Unity) is a lightweight
extensible dependency injection container with support for constructor,
property, and method call injection.
Unity 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. You can mock up shims (lightweight mock implementations) of objects that have strong concrete dependencies; such as database connections, network connections, ERP connections, and rich user interface components.
Dependency injection is a prime technique for building loosely coupled applications. It provides ways to handle the dependencies between objects. For example, an object that processes customer information may depend on other objects that access the data store, validate the information, and check that the user is authorized to perform updates. Dependency injection techniques can ensure that the customer class correctly instantiates and populates all of these objects, especially where the dependencies may be abstract.”
Unity 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. You can mock up shims (lightweight mock implementations) of objects that have strong concrete dependencies; such as database connections, network connections, ERP connections, and rich user interface components.
Dependency injection is a prime technique for building loosely coupled applications. It provides ways to handle the dependencies between objects. For example, an object that processes customer information may depend on other objects that access the data store, validate the information, and check that the user is authorized to perform updates. Dependency injection techniques can ensure that the customer class correctly instantiates and populates all of these objects, especially where the dependencies may be abstract.”
Characteristics
- Loosely coupled (Decoupled)
- Reusable
- Testable
- Easier to maintain and more flexible
- Removes the issues faced by the developers engaged in the component –based software engineering.
- More Readable code
Types of dependency
Injection with unity
- Compile Time (using the code)
- Run Time (using the config file)
Existing Dependency injection Frameworks
- Unity Container
- Ninject
- Spring for .Net
- Castle Windsor
The types of objects Unity can create
·
Can generate instance of any class that has
public constructor.
·
Need to call resolve method - container calls
constructor of that type and returns the result.
Lifetime of the object created
·
Default - unity creates new object every time
you resolve the type
·
You can specify the different life time (e.g.
can ask to maintain single instance - singleton)
Links
- Downloading
- Online help
- Discussions & issues
- Developer guide
How to use the dependency Injection with unity
(Compile Time)
Step 1:
Create new Console Project called UnityConsole.
Step 2:
Install the unity
framework using the Package Manager Console.
- Open the Package Manager Console (Visual Studio 2012 -> Tools->Library Package Manager ->Package Manager Console)
- Run the below command in the PM console
- This will install the Unity framework 3.0 and add the corresponding references in the project
Step 3:
Right click on project and add new item and then select
interface. Give name of the interface as IEmployee. Basically this interface
will define all the contracts which will used by the service or consumer. The methods
which we expose to the consumer.
IEmployee.cs
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Text;
using
System.Threading.Tasks;
namespace UnityConsole
{
public interface IEmployee
{
List<string> GetEmployeeNames();
}
}
Step 4:
Right click on project and add new class. Give name of the
class as Employee.cs
This class will implements the IEmployee Interface and
override all the methods defined by the interface to define the actual
functionality. The unity framework does not come in picture so far. So far we
creating the business logic which can be a separate component in your
Application. So this will help to separate your business logic and developer
can work independently. You can use any service or data access layer to fetch
the intermediate data from any data base.
Employee.cs
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Text;
using
System.Threading.Tasks;
namespace UnityConsole
{
public class Employee :IEmployee
{
public List<string>
GetEmployeeNames()
{
return new List<string>()
{
"Peter",
"Norbert",
"Micky",
"Albert"
};
}
}
}
Step 5:
Now the dependency injection
with unity framework comes into picture. Create a new class called
UnityFactory. This class will be used to register and resolve the references
based on the interfaces.
Basically two
methods of the UnityContainer class is used
- RegisterType
- Resolve
RegisterType method
of the UnityContainer class is used to register a type with the container. It
has 8 overloaded methods. We will use with two parameter method where the first
parameter is the Interface reference and second is the class which implements
that interface.
_container.RegisterType<IEmployee, Employee>();
When we use the
Resolve method, we will retrieve an object instance from the container for a
particular type.
IEmployee _employee = _container.Resolve<IEmployee>();
The class will look
like
UnityFactory.cs
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Text;
using
System.Threading.Tasks;
using
Microsoft.Practices.Unity;
namespace UnityConsole
{
public class UnityFactory
{
public static IEmployee GetInstance
{
get
{
using (IUnityContainer _container = new UnityContainer())
{
_container.RegisterType<IEmployee, Employee>();
IEmployee _employee = _container.Resolve<IEmployee>();
return _employee;
}
}
}
}
}
This kind of Dependency injection
with the unity framework is called compile time since the object instance is known
at the compile time.
Note: we have used the using
statement while creating the unitycontainer object since it implements the
IDisposable interface (unmanaged code) and it requires to garbage it manually.
If the constructor of the class
expects any parameter value then we can register like as below
_container.RegisterType<IEmployee, Employee>(new InjectionConstructor("abc"));
Step 6
Now
consumer comes into picture. This could be a separate component in your
Application. In our case Program.cs is the consumer where we will use the
Employee class using the unity framework.
Program.cs
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Text;
using
System.Threading.Tasks;
namespace UnityConsole
{
class Program
{
static void Main(string[] args)
{
IEmployee _employee = UnityFactory.GetInstance;
List<string> empNameList =
_employee.GetEmployeeNames();
foreach (string name in empNameList)
{
Console.WriteLine("Employee
Name is {0}.", name);
}
Console.ReadKey();
}
}
}
How to use the dependency Injection with unity
(Run Time or late binding)
All the
steps and code will remain same except the UnityFactory class. In this type of
injection we have config file where we define the mappings between the object
and interface and which will be used by the unity framework to resolve any
type.
Let us
assume we want to achieve the same functionality as we did in the above example
using the compile time binding. Your config file will look something like this:
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration,
Version=3.0.0.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</configSections>
<unity>
<containers>
<container>
<types>
<type name="EmployeeServiceProvider" type="UnityConsole.IEmployee,
UnityConsole" mapTo="UnityConsole.Employee, UnityConsole">
</type>
</types>
</container>
</containers>
</unity>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
Note: You
have referred the right version of the unity configuration dll. You can check
by checking the properties of the dll. Type and mapTo is the main attributes
used to tell the unity container to map between the interface and actual class.
The second argument in these is the namespace which contains the interface and
class.
UnityFactory.cs
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Text;
using
System.Configuration;
using
System.Threading.Tasks;
using
Microsoft.Practices.Unity;
using
Microsoft.Practices.Unity.Configuration;
namespace UnityConsole
{
public class UnityFactory
{
public static IEmployee GetInstance
{
get
{
using (IUnityContainer _container = new UnityContainer())
{
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(_container);
IEmployee _employee = _container.Resolve<IEmployee>("EmployeeServiceProvider");
return _employee;
}
}
}
}
}
Note: you
need to add the system.configuration dll reference in the solution.
Dependency Injection with unity (Singleton)
This is
basically used to maintain the single instance of the object during the life time
of the application. By default unity creates new object every time you resolve
the type. With the singleton pattern we can use the single instance of the
object from the unity container for the whole time. Let us consider the above
example. Employee.cs and IEmployee.cs classes will remain same.
Step 1:
Keep Employee.cs
and IEmployee.cs classes as it is.
Step 2:
Create a
new singleton class called UnitySingleton.cs. Some basics of the singleton
class
- The class is sealed as it cannot be
inherited further
- Only one instance of the class should
be created using the lock
The class will look like as
UnitySingleton.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Unity;
namespace UnityConsole
{
public sealed class UnitySingleton
{
static UnitySingleton _instance = null;
static readonly object objLock = new object();
private IEmployee _employeeProvider;
public static UnitySingleton Instance
{
get
{
lock (objLock)
{
if (_instance == null)
{
_instance = new UnitySingleton();
}
return _instance;
}
}
}
UnitySingleton()
{
using (IUnityContainer container = new UnityContainer())
{
RegisterTypes(container);
_employeeProvider =
container.Resolve<IEmployee>();
}
}
private static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IEmployee, UnityConsole.Employee>();
}
public IEmployee EmployeeProvider()
{
return _employeeProvider;
}
}
}
Step 3:
The
consumer (Program.cs) will use this singleton class as
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UnityConsole
{
class Program
{
static void Main(string[] args)
{
UnitySingleton singleton = UnitySingleton.Instance;
IEmployee _employee = singleton.EmployeeProvider();
List<string> empNameList =
_employee.GetEmployeeNames();
foreach (string name in empNameList)
{
Console.WriteLine("Employee Name is {0}.", name);
}
Console.ReadKey();
}
}
}