Introduction
In my last blog Unity Application Block, I introduced some of the concepts for using the Unity Application Block this blog introduces the added flexibility of using config files. This example will work either Web.Config or App.Config files, however it is possible to use other types of files.
Recap
We have a solution with 4 projects;
- InterfaceLibrary, this contains all of my interfaces.
- BusinessObjects, this contains my class file of the Customer Objects which implements the interface
- ServiceLayer, this populates and returns a BusinessObject
- FormApplication, this displays the information from the ServiceLayer.
We are using Unity to perform 3 tasks, Object Instantiation, Service Location and Dependency Injection.
Unity is instantiating the Service with the following code;
- var myService = myContainer.GetContainer().Resolve<IsvcCustomer>();
It is determining the location of the service with this;
- container = new UnityContainer()
- .RegisterType<ILogger, Logger>()
- .RegisterType<IsvcCustomer, svcCustomer2>();
Unity is automatically dealing with the Dependency Injection, that is when svcCustomer2 is instantiated it realises ILogger is required and creates an instance of Logger and passes this into the object.
Config Files
The obvious problem with the service location in the above example is that if the service changes (using the previous example) from svcCustomer to svcCustomer2 we need to do a recompile, which is sub-optimal . The solution is to store this information in a config file.
The first step is to register the configuration in the configSections tag of the xml file.
- <configSections>
- < section name="unity"
- type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
- Microsoft.Practices.Unity.Configuration, Version=1.2.0.0,
- Culture=neutral, PublicKeyToken=31bf3856ad364e35 " />
- </ configSections>
The configuration is made up of 2 sections the TypeAliases and the Containers.
In TypeAliases we list (amongst the Unity ones) our Types and what we want to call it (Alias) and which Assembly it can be found. Remember that XML is case sensitive.
- <typeAlias alias="SvcCustomer2" type="Service.svcCustomer2, Service" />
The Container section defines the name of the Container and shows the mapping between interfaces and their concrete types
- <type type="ILogger" mapTo="Logger" />
A complete app.config can be found at the end of this post.
Code Change
To enable your application to read the Config file you need to reference the following namespace Microsoft.Practices.Unity.Configuration which can be found in the Microsoft.Practices.Unity.Configuration.dll assembly.
then change the code
- container = new UnityContainer()
- .RegisterType<ILogger, Logger>()
- .RegisterType<IsvcCustomer, svcCustomer2>();
to
- container = new UnityContainer();
- var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
- section.Containers["container"].Configure(container);
Which gets the <unity> config section and populates the UnityContainer “container” with “container” section from the <containers> section.
Conclusion
You can now configure your services on the fly, which I think is a more elegant solution than doing it in code.
I do not think this will be my last post on Unity as I would like to look at an example with WCF and take a look at other ways of performing the Dependency Injection.
App.Config for this project
- <?xml version="1.0" encoding="utf-8" ?>
- < configuration>
- < configSections>
- < section name="unity"
- type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
- Microsoft.Practices.Unity.Configuration, Version=1.2.0.0,
- Culture=neutral, PublicKeyToken=31bf3856ad364e35 " />
- </ configSections>
- < unity>
- < typeAliases>
- <!-- Lifetime manager types -->
- < typeAlias alias="singleton"
- type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
- Microsoft.Practices.Unity " />
- < typeAlias alias="external"
- type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager,
- Microsoft.Practices.Unity " />
- <!-- User-defined type aliases -->
- < typeAlias alias="ILogger" type="InterfaceLibrary.ILogger, InterfaceLibrary" />
- < typeAlias alias="ISvcCustomer" type="InterfaceLibrary.IsvcCustomer, InterfaceLibrary" />
- < typeAlias alias="Logger" type="Service.Logger, Service" />
- < typeAlias alias="SvcCustomer" type="Service.svcCustomer, Service" />
- </ typeAliases>
- < containers>
- < container name="container">
- < types>
- < type type="ILogger" mapTo="Logger" />
- < type type="ISvcCustomer" mapTo="SvcCustomer" />
- </ types>
- </ container>
- </ containers>
- </ unity>
- </ configuration>
No comments:
Post a Comment