Monday, January 3, 2011

Unity Study Notes (3)

In this article, we are going to talk using Configure file to do type mapping instead of writing code to register type mapping.

Notice, for the code in Unity Study Notes(1) and Unity Study Note(2), we just need to reference the Microsoft.Practices.Unity.dll and using Microsoft.Practices.Unity namespace, when we use configuration file, we need to add one more dll:Microsoft.Practices.Unity.Configuration.dll and using Microsoft.Practices.Unity.Configuration namespace. And also ConfigurationManager class comes from System.Configuration namespace, so we should also reference System.Configuration.dll and include using System.Configuration.

The same thing, we write the IWriteService interface and FirstWriteService, SecondWriteService Classes, We also write the PrintServiceBaseClass and PrintService Class.

public interface IWriteService
{
void Write(string msg);
}

public class FirstWriteService : IWriteService
{
public void Write(string msg)
{
Console.WriteLine("First Write Service: " + msg);
}
}

public class SecondWriteService : IWriteService
{
public void Write(string msg)
{
Console.WriteLine("Second Write Servive: " + msg);
}
}

public abstract class PrintBaseClass
{
public abstract void Print(string msg);
}

public class PrintService : PrintBaseClass
{
public override void Print(string msg)
{
Console.WriteLine("Print Service: " + msg);
}
}

Now let's add a configuration file for mappings.

< ?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 name="myContainer">
< types>
< type type="MyUnityPractice.IWriteService,MyUnityPractice" name="FirstWrite"
mapTo="MyUnityPractice.FirstWriteService,MyUnityPractice" />
< type type="MyUnityPractice.IWriteService,MyUnityPractice" name="SecondWrite"
mapTo="MyUnityPractice.SecondWriteService,MyUnityPractice" />
< type type="MyUnityPractice.PrintBaseClass,MyUnityPractice"
mapTo="MyUnityPractice.PrintService,MyUnityPractice" />
< /types>
< /container>
< /containers>
< /unity>
< /configuration>

And in the main Entry we can resolve our types:

IUnityContainer container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

section.Configure(container,"myContainer");

IWriteService service1 = container.Resolve("SecondWrite");
service1.Write("Hello 2011");

PrintBaseClass service2 = container.Resolve();
service2.Print("2011");

Notice, in our this example, as there is only one container, we can also don't specify the container name, like:

section.Configure(container);

But sometimes, in the configure file there are more than 1 container, in that case the 2nd parameter should be the container name.

We can also use ResolveAll method to get the IWriteService Collection:

IEnumerable< IWriteService> services = container.ResolveAll< IWriteService>();
foreach (IWriteService service in services)
{
service.Write("Hello");
}

Notice: We can use the following code to load configuration file:

IUnityContainer container = new UnityContainer()
.LoadConfiguration("myContainer");

This code can be used to replace:

IUnityContainer container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

And if using this code, we don't need to have System.Configuration namespace.

If the container doesn't have a name and there is only 1 container, that is in the configure file:

< containers>
< container>
....
< /container>
< /containers>

We can also use code like following to configure the container:

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

Normally, when we add a app.config or web.config file, we don't need to worry about the configue file name. But in some cases, developers may have a configure file with different name, for example: other.config, in this case, we need have some code to read the configure file:

using System.Configuration;
var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = "other.config" };
System.Configuration.Configuration configuration =
ConfigurationManager.OpenMappedExeConfiguration(fileMap,
ConfigurationUserLevel.None);
var unitySection = (UnityConfigurationSection)configuration.GetSection("unity");

When specify the type in configuration file, the format of the type is:

< namespace>.< typename>, < assembly>

the assembly can be strong named as well.

The sample code is at this link:

https://docs.google.com/uc?id=0BwzR-spEXHBFOTAyYzcxMDAtYTA3MS00YmU4LWFmYmQtNjM0OGQ4NTRjYzIw&export=download&hl=en

No comments: