Click here to Skip to main content
15,867,330 members
Articles / Programming Languages / C# 4.0

A basic introduction to the Unity Application Block

Rate me:
Please Sign up or sign in to vote.
3.95/5 (20 votes)
23 Sep 2009CPOL2 min read 96.6K   39   14
Unity application block, Inversion of Control, and Dependency Injection.

Introduction

With its latest release, the Enterprise Library from Microsoft introduces a new component named Unity. This application block provides an easy path to implement the IoC pattern, and consequently the Dependency Injection pattern.

All the references for the Enterprise Library documentation can be found at the end of the article.

Background

Inversion of Control and Dependency Injection are the key points to understand how Unity works and the benefits of including it in our projects. If you want a deep dive on these patterns: http://martinfowler.com/articles/injection.html.

The scope of this article is writing code that is loosely coupled. Let's examine the following DummyLogger class:

C#
public class DummyLogger
{
    private IWriter _selectedWriter;

    public DummyLogger()
    {
        //The container class is in charge for the initialization of the interface. 
        //the result is a strong dependency between the two objects
        _selectedWriter = new ConsoleWriter();
    }

    public void WriteOutput(string msg)
    {
        _selectedWriter.Write(msg);
    }
}

The first thing that comes to mind to break the relationship between the two objects is to delegate the creation of the class member to someone else:

C#
public class DummyLogger
{
    private IWriter _selectedWriter;

    public void SetWriter(IWriter writer)
    {
        _selectedWriter = writer;
    }

    public void WriteOutput(string msg)
    {
        _selectedWriter.Write(msg);
    }
}

Nothing new until now. This can be interpreted as a trivial implementation of the IoC pattern. The contained object is no more controlled by its container class.

But what if we don't care about the real implementation of the IWriter interface ? Here's where Unity and Dependency Injection comes. The concrete implementation of the class member will be "injected" by Unity depending on its configuration. The first thing we need to do is expose the class/interface with its get/set methods and mark it with the [Dependency] attribute to make it visible to the application block.

C#
public class DummyLogger
{

    private IWriter _selectedWriter;

    public void SetWriter(IWriter writer)
    {
        _selectedWriter = writer;
    }

    public void WriteOutput(string msg)
    {
        _selectedWriter.Write(msg);
    }
}

Behind the scenes, each class/interface decorated with the [Dependency] attribute will be created according to the Unity container's configuration. This can be done programmatically or via the .config file.

XML
<type type="George2giga.TestUnity.Library.IWriter,George2giga.TestUnity.Library" 
   mapTo="George2giga.TestUnity.Library.ConsoleWriter,George2giga.TestUnity.Library" />

Using the code

Given below is a basic implementation of Unity. Here's the class diagram of our sample application:

Image 1

IWriter, the interface is shared between the logging providers:

C#
public interface IWriter
{
    void Write(string msg);
}

Of the three logging providers, depending on the configuration, one of them will be "injected" to create the IWriter instance:

C#
public class ConsoleWriter : IWriter
{
    #region IWriter Members

    public void Write(string msg)
    {
        Console.WriteLine(msg);
        Console.ReadLine();
    }

    #endregion
}

public class FileWriter : IWriter
{
    #region IWriter Members

    public void Write(string msg)
    {
        using (StreamWriter streamWriter = 
               new StreamWriter("c:\\TestUnity.txt",true))
        {
            streamWriter.WriteLine(msg);
        }
    }
    #endregion
}

public class EventViewerWriter : IWriter
{
    #region IWriter Members

    public void Write(string msg)
    {
        EventLog.WriteEntry("TestUnity", msg, 
                            EventLogEntryType.Information);
    }

    #endregion
}

The logging class contains the dependency property:

C#
public class DummyLogger
{
    private IWriter selectedWriter;

    [Dependency]
    public IWriter SelectedWriter
    {
        get { return selectedWriter; }
        set { selectedWriter = value; }
    }

    public void WriteOutput(string msg)
    {
        selectedWriter.Write(msg);
    }
}

The entry point of the application is responsible for the initialization of the Unity container:

C#
class Program
{
    static void Main(string[] args)
    {
        IUnityContainer container = new UnityContainer();
        UnityConfigurationSection section = 
          (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
        section.Containers.Default.Configure(container);
        DummyLogger dummyLogger = container.Resolve<DummyLogger>();
        dummyLogger.SelectedWriter.Write("Hello");}
}

Here is the App.config:

XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
      <section name="unity" 
         type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, 
               Microsoft.Practices.Unity.Configuration" />
    </configSections>
    <unity>
      <containers>
        <container>
          <types>
            <type 
               type="George2giga.TestUnity.Library.IWriter,George2giga.TestUnity.Library" 
               mapTo="George2giga.TestUnity.Library.ConsoleWriter,
                      George2giga.TestUnity.Library" />
          </types>
        </container>
      </containers>
    </unity>
</configuration>

Points of interest

Design patterns are without doubt a very interesting argument. With Unity, we are able to implement two of them in a very easy way. Dependency Injection allows us to create code that is decoupled, where we can create dependencies without hard-coding anything on our project.

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Minalabs
United Kingdom United Kingdom
Giorgio Minardi is a .Net consultant actually working in UK after diffent years spent in Italy working on enteprise clients.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Shreekanth Gaanji25-Mar-16 20:48
Shreekanth Gaanji25-Mar-16 20:48 
GeneralMy vote of 2 Pin
Gaurav.WhiteLotus24-Feb-14 19:38
Gaurav.WhiteLotus24-Feb-14 19:38 
GeneralMy vote of 2 Pin
Reza Ahmadi20-Feb-14 20:03
Reza Ahmadi20-Feb-14 20:03 
GeneralMy vote of 5 Pin
vaghelabhavesh3-Apr-13 0:37
vaghelabhavesh3-Apr-13 0:37 
SuggestionCorrection for the code snippet Pin
E L N I N O27-Mar-12 19:27
E L N I N O27-Mar-12 19:27 
GeneralMy vote of 5 Pin
Leo5619-Sep-11 1:19
Leo5619-Sep-11 1:19 
GeneralMy vote of 5 Pin
Rhuros19-May-11 0:40
professionalRhuros19-May-11 0:40 
GeneralI like it! Pin
steliodibello8-Jun-10 22:07
steliodibello8-Jun-10 22:07 
QuestionWrong code segment? Pin
John Whitmire6-Oct-09 7:10
professionalJohn Whitmire6-Oct-09 7:10 
AnswerRe: Wrong code segment? Pin
Giorgio Minardi7-Oct-09 4:09
Giorgio Minardi7-Oct-09 4:09 
GeneralVery basic Pin
Sohel_Rana24-Sep-09 22:34
Sohel_Rana24-Sep-09 22:34 
GeneralMy vote of 2 Pin
BigTuna23-Sep-09 4:48
BigTuna23-Sep-09 4:48 
GeneralRe: My vote of 2 Pin
Giorgio Minardi23-Sep-09 8:39
Giorgio Minardi23-Sep-09 8:39 
GeneralRe: My vote of 2 Pin
Massimiliano Peluso "WeDev Limited"23-Sep-09 22:33
Massimiliano Peluso "WeDev Limited"23-Sep-09 22:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.