Sdílet prostřednictvím


Unity 2 – Configuring Unity at Runtime (Part1)

I’m real fan of Unity, I already worked with other IoCs, but Unity remains my favorite.

In the upcoming posts, I will explain you how to :

  • Configure in Runtime or in Design time;
  • Make the best use of it

In this post I will assume that you already know about ALL the advantages of using the IoC pattern. You can download Unity here.

Simple scenario

First of all, we will create the project that will help us for all the samples. I will name it UnityTest.

First and foremost, let’s add a reference to Microsoft.Practices.Unity.

Then create an interface named IMyComponent:

Code Snippet

  1. public interface IMyComponent
  2. {
  3.     string Run(int i);
  4. }

Implement that interface in the MyComponent class:

Code Snippet

  1. public class MyComponent : IMyComponent
  2. {
  3.     #region IMyComponent Members
  4.     int loopIndex = 0;
  5.     public MyComponent()
  6.     {
  7.         loopIndex = 0;
  8.     }
  9.     public string Run(int nb)
  10.     {
  11.         StringBuilder sb = new StringBuilder();
  12.         sb.Append("Hello : ");
  13.         for(int i=0; i<nb;i++)
  14.         {
  15.             loopIndex = loopIndex +i;
  16.             sb.Append(loopIndex.ToString()).Append(" ");
  17.         }
  18.         return sb.ToString();
  19.     }
  20.  
  21.     #endregion
  22. }

Finally, implement Program as follows (register, then resolve the types):

Code Snippet

  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         IUnityContainer container;
  6.         // Use the runtime configuration
  7.         container = new UnityContainer();
  8.         container.RegisterType<IMyComponent,MyComponent>();
  9.  
  10.         // Resolve IMyComponent
  11.         IMyComponent obj = container.Resolve<IMyComponent>();
  12.         IMyComponent objBis = container.Resolve<IMyComponent>();
  13.  
  14.         Console.WriteLine(obj.Run(5));
  15.         Console.WriteLine(objBis.Run(5));
  16.         Console.ReadKey();
  17.  
  18.     }
  19. }

What was actually done, was to instantiate the Unity container, and then register a new couple inside it. From then on, every time I will need an implementation of IMyComponent, Unity will instantiate MyComponent through a call to Resolve.

image

Singleton scenario

If I want to have MyComponent as a singleton, I will have to register it as an instance:

Code Snippet

  1. container.RegisterInstance<IMyComponent>(new MyComponent());

Then, each time I will need an instance of IMyComponent, Unity will return me the registered singleton.

Code Snippet

  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         IUnityContainer container;
  6.         // Use the runtime configuration
  7.         container = new UnityContainer();
  8.         container.RegisterInstance<IMyComponent>(new MyComponent());
  9.  
  10.         // Resolve IMyComponent
  11.         IMyComponent obj = container.Resolve<IMyComponent>();
  12.         IMyComponent objBis = container.Resolve<IMyComponent>();
  13.  
  14.         Console.WriteLine(obj.Run(5));
  15.         Console.WriteLine(objBis.Run(5));
  16.         Console.ReadKey();
  17.  
  18.     }
  19. }

image

 

Aliases scenario

I will create a new class MyComponentFr that will also implement the IMyComponent interface.

Code Snippet

  1. public class MyComponentFr : IMyComponent
  2. {
  3.     #region IMyComponent Members
  4.     int loopIndex = 0;
  5.     public MyComponentFr()
  6.     {
  7.         loopIndex = 0;
  8.     }
  9.     public string Run(int nb)
  10.     {
  11.         StringBuilder sb = new StringBuilder();
  12.         sb.Append("Bonjour : ");
  13.         for (int i = 0; i < nb; i++)
  14.         {
  15.             loopIndex = loopIndex + i;
  16.             sb.Append(loopIndex.ToString()).Append(" ");
  17.         }
  18.         return sb.ToString();
  19.     }
  20.  
  21.     #endregion
  22. }

This is exactly the same code as the initial MyComponent except that the text is in French. The following code demonstrates how to use aliases to return different implementations of IMyComponent, depending on an alias :

Code Snippet

  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         IUnityContainer container;
  6.         const string FRENCH = "fr";
  7.         const string DEFAULT = "us";
  8.         // Use the runtime configuration
  9.         container = new UnityContainer();
  10.         container.RegisterType<IMyComponent, MyComponent>(DEFAULT);
  11.         container.RegisterType<IMyComponent, MyComponentFr>(FRENCH);
  12.         // Configure aliases with singleton
  13.         // container.RegisterInstance<IMyComponent>(DEFAULT, new MyComponent());
  14.  
  15.         // Resolve IMyComponent
  16.         IMyComponent obj = container.Resolve<IMyComponent>(DEFAULT);
  17.         IMyComponent objFr = container.Resolve<IMyComponent>(FRENCH);
  18.  
  19.         Console.WriteLine(obj.Run(5));
  20.         Console.WriteLine(objFr.Run(5));
  21.  
  22.         Console.ReadKey();
  23.     }
  24. }

As you can see, I just have to register the implementation with an alias.

image