Montag, 18. Mai 2015

Injecting a non-native data type via constructor using a Unity XML configuration

I thought it could be helpful to write a few lines about the following problem as I couldn't find any blog, technet or stackoverflow article providing a clear and easy-to-follow solution.

In one of my projects, I have a class that receives a data repository via a constructor injection. For a better illustration, find a simplified version of the class, the repository interface and implementation below.

namespace UnityTest
{
    public interface IRepository
    {
        object GetEntry(int id);
    }
}
using System;

namespace UnityTest
{
    public class Repository : IRepository
    {
        public object GetEntry(int id)
        {
            throw new NotImplementedException();
        }
    }
}
namespace UnityTest
{
    public class MyClass
    {
        IRepository repository;

        public MyClass(IRepository repository)
        {
            this.repository = repository;
        }

        public void DoSomeThing()
        {
            this.repository.GetEntry(0);
        }
    }
}

Pretty straight forward implementation as you can see. Injecting the actual type of the IRepository interface is now quite easy when using a programmatically approach to configure the unity container (add a reference to Unity via NuGet if not done yet).

IUnityContainer container = new UnityContainer();
container.LoadConfiguration();
var myClass = container.Resolve<MyClass>();
myClass.DoSomeThing();

While that works fine, I thought it could be a good idea to extract the container configuration into an XML file as I won't have to recompile the application to change the interface binding. And that is where the tricky part comes in. Actually I thought it couldn't be a big deal to put that into an XML file but it turned out that this is not that obvious as you might think  - and as described before, there aren't that many resources out there in the net that describe this in a simple way.

So this is the simplest solution that I came up with to inject the IRepository implementation via a constructor using an XML based Unity configuration:
<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">
 
    <alias alias="IRepository" type="UnityTest.IRepository, UnityTest" />
    <alias alias="Repository" type="UnityTest.Repository, UnityTest" />
 
    <container>
      <register mapto="Repository" type="IRepository" />   
     
      <register name="MyClass" type="UnityTest.MyClass, UnityTest">
        <constructor>
          <param name="repository" type="IRepository">
            <dependency name="IRepository" />
          </param>
        </constructor>
      </register>
     
    </container>
   
  </unity>
 
</configuration>

Hope that helps someone (at least it does help myself, should I run into that again in the future).

Keine Kommentare:

Kommentar veröffentlichen