Tuesday, 23 October 2012

Unity 2.0 General Guidelines

This entry shows from an easy point of view the Unity 2.0 functionality and the main concepts and components related to it.
My goal is to convey the concepts as though we were on the street talking about the weather or so.
There are three functionalities Unity 2.0 provides by implementing the following design patterns:

1) Dependency Injection pattern. Basically, this pattern can be used when you need to create class instances without assigning memory explicitly. 
2) Inversion of control pattern. This pattern decouples how the class instances are created. That is to say,
3) Interception pattern. Basically, this pattern permits to implement additional functionality in runtime.


4) Factory pattern. This pattern has the goal of providing object instances and manage how this instances are created.

Unity 2.0 provides the following functionality in order to implement design patterns properly and give the software architecture a good design approach.



The following example implements a Factory Class which provides the instances requested by the code. This factory class implements the Factory Pattern, and therefore it decouples the mechanism of instance creation from the application code. 

The Factory class implementation is based on Unity Container. Unity Container manages the dependencies between the set of objects that takes part of the application efinition. As you may know, objects have dependencies with other objects.  That is to say, a class called GreetingFormal have a constructor that exposes a parameter of a specific type (for instance, GreetingLanguageSpanish). When a  GreetingFormal object is created, Unity container injects a new instance of the specific type (GreetingLanguageSpanish)  to the constructor and therefore the parameter gets a new value or reference.  This injection is made by the container. Since that Unity Container manages the relationship creation among the objects, the application source code is out of this responsibility and therefore decoupling instantiation processes from the application is a fact.
Finally, as you can see, application does not need to be concerned about how to establish all dependencies. In addition, application does not need to assign a specific instance of a specific type to a specific application variable. Instead, it is Unity Container the responsible of providing the current instance of a specific type. That is called Inversion of control. It is call inversion of control because it is the container who manages the instance creation instead of being the application by using the “new” instruction.

With all this stuff described, indeed there is a main goal that justifies all these pattern considerations.  Decoupling the instance management from the application.

This example shows how you can implement these three patterns by using Unity 2.0

Firstly, Here you are the factory (be aware that the code style could be improved, but the goal of this entry is to show how to implement the patterns based on Unity implementation).

The factory class is the following.

public static class FactoryProvider
    {
        private static IUnityContainer container;
        public  static Object getInstance(Type type,string name)
        {
            if (container == null)
            {

                container = new UnityContainer();
                container.LoadConfiguration();
                              
                 Object obj = container.Resolve(type,name);
              
                return obj;
            }
            else
            {
                Object obj = (Object)container.Resolve(type, name);
                return obj;
               
            }
 
        }
    }

This class is the implementation of the so-called Factory Pattern, and encapsulates all object creation implementations.
Application has only to use the static Factory class by invocating the method getInstace in order to get a new instance.
IGreeting os= (IGreeting)FactoryProvider.getInstance(typeof(IGreeting), "greetingSpanish");


The container is in charge of establishing all dependencies when they are required. Therefore, unity container is the responsible of instancing all dependences among objects. The main application does not know anything about this issue. It just uses instances by requesting them to the Factory class.
In order to define the dependencies between objects, Unity provides two mechanisms to get it. In this example I use the common Unity section included within the app.config file.
<?xml version="1.0"?>
<configuration>

  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
 
  </configSections>
 
  <!-- unity section--> 
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <namespace name="GreetingClient" />
    <assembly name="GreetingClient" />
    <alias alias="IGreetingLanguage" type="IGreetingLanguage, GreetingLanguageEnglish" />
    <container>
      <!-- Type instance. This is a instance of the GreetingLanguageEnglish type.-->
      <!--<instance name="lenglish"  type ="IGreetingLanguage" typeConverter="GreetingTypeConverter"/>-->

      <register type="IGreetingLanguage" name="lenglish" mapTo="GreetingLanguageEnglish">
        <lifetime type="singleton"/>
        <method name="establishLanguage">
           <param name="language">
            <value value="slang"/>
          </param>
         
        </method>
      </register>
     
      <register type="IGreetingLanguage" name="lspanish" mapTo="GreetingLanguageSpanish">
        <lifetime  type="singleton"/>
          <method name="establishLanguage">
            <param name="language">
              <value value="formal"/>
            </param>
        </method>
      </register>
     
      <!-- This is a registered  GreetingFormal object whose constructor accept a IGreetingLanguage parameter-->
      <register type="IGreeting" name="greetingEnglish" mapTo="GreetingFormal">
        <constructor>
          <param  dependencyName="lenglish" name="language" type="IGreetingLanguage"/>
        </constructor>
       </register>

      <register type="IGreeting" name="greetingSpanish" mapTo="GreetingFormal">
        <constructor>
          <param  dependencyName="lspanish" name="language" type="IGreetingLanguage"/>
        </constructor>
      </register>
    </container>
    </unity>
  </configuration>


Several remarks about the unity section. 

Firstly, I would like to explain the example in order to understand better the xml definition.

This example is very simple.

There is a class called GreetingFormal that implements the IGreeting interface. The class has a method called “greeting” that print a greeting message. This message can be an English message or a Spanish message, depend on the class implementing IGreetingLanguage it uses. Class constructor accepts an IGreetingLanguage-implemented class as constructor argument. The Unity container established all injections which are defined within the Unity section of the app.config file.

<register type="IGreeting" name="greetingEnglish" mapTo="GreetingFormal">
        <constructor>
          <param  dependencyName="lenglish" name="language" type="IGreetingLanguage"/>
        </constructor>
       </register>

Each GreetingLanguage classes can be configured to decide which the language usage is: formal or informal.

<register type="IGreetingLanguage" name="lenglish" mapTo="GreetingLanguageEnglish">
        <lifetime type="singleton"/>
        <method name="establishLanguage">
           <param name="language">
            <value value="slang"/>
          </param>
         
        </method>
      </register>
     

This file, as a conclusion, defines the dependencies among objects. Unity container instantiates all references and relationships.

container = new UnityContainer();
container.LoadConfiguration();

Now is the turn of the Inversion of control. Application uses the Factory class to obtain a specific instance of an object. It is not the application which instantiates (new keyword). It is the container wrapped by the Factory class which does.
Application have only to use the Factory method (getInstance ) to obtain the  current one.

IGreeting os= (IGreeting)FactoryProvider.getInstance(typeof(IGreeting), "greetingSpanish");

The following code list shows each component of this example.

Factory class that shows how the factory pattern is:

public static class FactoryProvider
    {
        private static IUnityContainer container;
        public  static Object getInstance(Type type,string name)
        {
            if (container == null)
            {
                container = new UnityContainer();
                container.LoadConfiguration();
                              
                 Object obj = container.Resolve(type,name);
                return obj;
            }
            else
            {
                Object obj = (Object)container.Resolve(type, name);
                return obj;
               
            }
 
        }
    }

With regard to Language features, here there is the code.This is the interface implementing the language classes.

public interface IGreetingLanguage
    {
       
        string getMessage();
    }

And these are the language classes.

public class GreetingLanguageEnglish : IGreetingLanguage
    {
        private string message;
       
        public void establishLanguage(string language)
        {
            if (language.CompareTo("formal") == 0)
            {
                message = "Dear ";
            }
            else
            {
                message="Hi ";
            }
           
        }
        string IGreetingLanguage.getMessage()
        {
            return message;
        }

       
    }

public class GreetingLanguageSpanish:IGreetingLanguage
    {
        private string message;
      
       
        public void establishLanguage(string language)
        {

            if (language.CompareTo("formal") == 0)
            {
                message = "Estimado ";
            }
            else
            {
                message = "Hola ";
            }
           
        }

       string getMessage()
        {
            return message;
        }
 
   
    }

This is the class that manages the Greetings.

public interface IGreeting
    {
       
        string greeting(string name);
       

    }


public  class GreetingFormal : IGreeting
    {

        private string greetingMessage;
        public GreetingFormal(IGreetingLanguage language)
        {

            greetingMessage = language.getMessage();
          
        }

        #region IGreeting Members

        public  virtual string greeting(string name)
        {
          

            return greetingMessage +  " " + name;
        }

        #endregion

        #region IGreeting Members


      

        #endregion
    }

Finally, the console application instanciates the GreetingFormal class without knowing how the dependency injection is conformed and delegating the instantiation process to the Unity Container.

static void Main(string[] args)
        {


            Console.WriteLine("Start");
      
            IGreeting os= (IGreeting)FactoryProvider.getInstance(typeof(IGreeting), "greetingSpanish");

            IGreeting oe = (IGreeting)FactoryProvider.getInstance(typeof(IGreeting), "greetingEnglish");

            Console.WriteLine (os.greeting("Fernando"));
            Console.WriteLine(oe.greeting("Ferdinand"));

            Console.WriteLine("Finish");
           
}

The console result is the following:


           



No comments:

Post a Comment