Friday, 27 November 2009

Unity Application Block, using Configuration Files.

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;

Code Snippet
  1. var myService = myContainer.GetContainer().Resolve<IsvcCustomer>();

It is determining the location of the service with this;

Code Snippet
  1. container = new UnityContainer()
  2. .RegisterType<ILogger, Logger>()
  3. .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 Smile. 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.

Code Snippet
  1. <configSections>
  2. < section name="unity"
  3. type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
  4. Microsoft.Practices.Unity.Configuration, Version=1.2.0.0,
  5. Culture=neutral, PublicKeyToken=31bf3856ad364e35 " />
  6. </ 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.

Code Snippet
  1. <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

Code Snippet
  1. <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

Code Snippet
  1. container = new UnityContainer()
  2. .RegisterType<ILogger, Logger>()
  3. .RegisterType<IsvcCustomer, svcCustomer2>();

to

Code Snippet
  1. container = new UnityContainer();
  2. var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
  3. 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

Code Snippet
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. < configuration>
  3. < configSections>
  4. < section name="unity"
  5. type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
  6. Microsoft.Practices.Unity.Configuration, Version=1.2.0.0,
  7. Culture=neutral, PublicKeyToken=31bf3856ad364e35 " />
  8. </ configSections>
  9. < unity>
  10. < typeAliases>

  11. <!-- Lifetime manager types -->
  12. < typeAlias alias="singleton"
  13. type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
  14. Microsoft.Practices.Unity " />
  15. < typeAlias alias="external"
  16. type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager,
  17. Microsoft.Practices.Unity " />

  18. <!-- User-defined type aliases -->
  19. < typeAlias alias="ILogger" type="InterfaceLibrary.ILogger, InterfaceLibrary" />
  20. < typeAlias alias="ISvcCustomer" type="InterfaceLibrary.IsvcCustomer, InterfaceLibrary" />
  21. < typeAlias alias="Logger" type="Service.Logger, Service" />
  22. < typeAlias alias="SvcCustomer" type="Service.svcCustomer, Service" />
  23. </ typeAliases>
  24. < containers>
  25. < container name="container">
  26. < types>
  27. < type type="ILogger" mapTo="Logger" />
  28. < type type="ISvcCustomer" mapTo="SvcCustomer" />
  29. </ types>

  30. </ container>
  31. </ containers>

  32. </ unity>


  33. </ configuration>

No comments:

Post a Comment