Unity Configuration with Both Code and a Config File

by Larry Spencer Sunday, February 5, 2012 7:23 PM

When configuring your Unity dependency injection container, you can use code or a  config file. Code has the advantages of simplicity and compile-time checking. The config file wins on flexibility. This post shows how you can have the best of both worlds.

The procedure is to establish the default behavior in code, and then call IUnityContainer.LoadConfiguration() to bring in any overrides.

In this example, we want our application to run under the “en-us” culture, but allow overrides from a config file.

 

using System;
using System.Collections;
using System.Configuration;
using System.Globalization;
using System.Linq;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

namespace UnityDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var unity = new UnityContainer())
            {
                // Register the default culture.
                unity.RegisterType<IFormatProvider, CultureInfo>
                    (new InjectionConstructor("en-us"));

                // We register another type just to prove that its 
                // registration survives the loading of the config file.
                unity.RegisterType<IList, ArrayList>();

                Console.WriteLine("Configured in code:");
                ShowAmount(unity.Resolve<IFormatProvider>(),  1234.56M);
                ShowListType(unity);

                // Override with the config file, if there is a unity section.
                if (ConfigurationManager.GetSection("unity") != null)
                {
                    unity.LoadConfiguration();

                    Console.WriteLine();
                    Console.WriteLine("After loading the config file:");
                    ShowAmount(unity.Resolve<IFormatProvider>(), 1234.56M);
                    ShowListType(unity);
                }

                Console.ReadLine();
            }
        }

        private static void ShowAmount(IFormatProvider fp, decimal money)
        {
            var fi = fp.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo;
            Console.WriteLine(String.Format(fp, "{0:C}", money));
        }

        private static void ShowListType(IUnityContainer unity)
        {
            var reg = unity.Registrations.Single(r => r.RegisteredType==typeof(IList));
            Console.WriteLine("{0} -> {1}", 
                reg.RegisteredType.Name, reg.MappedToType.Name);
        }
    }
}

 

In line 18, we use code to register the default culture. For demonstration purposes, we also register a concrete type for IList.

In line 32, we bring in the Danish culture from the app.config.

 

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <assembly  name="UnityDemo"/>
    <container>
      <register type="System.IFormatProvider" mapTo="System.Globalization.CultureInfo" >
        <constructor>
          <param name="name" value="da" />
        </constructor>
      </register>
    </container>
  </unity>
</configuration>

 

The output shows that the money is now printed in Danish style, and the IList registration survived the call to LoadConfiguration().

That’s it! Load your configuration in code, and then override with LoadConfiguration() and you get the best of both worlds.

Tags: , , , ,

All | All | Dependency Injection | Dependency Injection

About the Author

Larry Spencer

Larry Spencer develops software with the Microsoft .NET Framework for ScerIS, a document-management company in Sudbury, MA.