colinramsay.co.uk

Basic Windsor Usage with the Repository Pattern

15 Sep 2007

I've been interested in using the Repository pattern in an application for a while now; same goes for Windsor. When prototyping with repositories it became clear that I could use them together in a fairly simple way which would serve as a good introduction to both.

Let me begin by showing how I have set up Windsor; I will be using a simple console application to demonstrate the code. Starting a new Console Application Project in Visual Studio, I added references to Castle.Core.dll, Castle.DynamicProxy2.dll, Castle.MicroKernel.dll, Castle.Windsor.dll and nunit.framework.dll. I also added an app.config file to store the Windsor configuration.

Our first snippet of code initialises the Windsor container. Put this in the Main method of your console app:

IWindsorContainer container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));

All the above code does is create a new instance of the Windsor container. Notice that we're using XmlInterpreter to allow us to access our Winsdor configuration in the app.config. We'll fill in those configuration details later.

Let's now create a few classes for us to work with:

public class IGenericRepository<T> { }public class TestGenericRepository<T> : IGenericRepository<T> { }

Simple empty stubs for demonstration purposes, hopefully no explanation is necessary. We could use this as follows:

TestGenericRepository<T> repo = new  TestGenericRepository<T>();repo.DoSomething();

However, I would prefer to have a slightly simpler syntax like this:

Repository<object>.DoSomething();

In order to do this, we can create a static class which wraps up access to a repository instance provided by Windsor:

public static class Repository<T>
{
    public static IRepository InnerRepository
    {
        get
        {
            return IoC.Container.Resolve<IGenericRepository<T>>();
        }
    }
}

We're grabbing a WindsorContainer instance and calling the Resolve method to get the configured implementation of IGenericRepository<T>. There's some trickery going on there with another static class called IoC:

public static class IoC{

    private static IWindsorContainer _innerContainer;

    public static IWindsorContainer Container
    {
        get
        {
            return _innerContainer;
        }
    }

    public static void Initialise(IWindsorContainer container)
    {
        _innerContainer = container;
    }
}

IoC, shamelessly stolen from Ayende's Rhino Commons, allows access to an initialised container throughout your application. This is how I use it in this application:

IoC.Initialise(container);

All we're doing is putting our previously initialised container somewhere that we can access from elsewhere in our application, such as the InnerRepository property of our static Repository class.

Now we need to configure Windsor to supply us with the right implementation of IGenericRepository<T>. Add this code to your app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<configSections>
		<section
			name="castle"
			type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
	</configSections>
	<castle>
		<components>
			<component
				id="generic.repository"
				service="WindsorTest.IGenericRepository`1, WindsorTest"
				type="WindsorTest.TestGenericRepository`1, WindsorTest" />
		</components>
	</castle>
</configuration>

A lot of this is for the basic setup of Windsor, but the bit we're interested in is the component node. We've specified a unique id for our component, then the service defines the interface we're going to be providing an implementation of. That implementation is specified in the type attribute value. Note the slightly strange "`1" notation - that's the CLR string representation of a generic argument (in C# it would look like IGenericRepository<T>). With this single node we're telling Windsor what implementation of IGenericRepository<T> Windsor should provide.

This means that the call to WindsorContainer.Resolve in our static Repository<T> class will return an instance of TestGenericRepository<T> - all our wiring up is now complete. We can check that everything is working with an extra line in our Console app:

Assert.IsInstanceOfType(typeof(TestGenericRepository<object>), Repository<object>.InnerRepository);

We're just checking that the IGenericRepository<T> implementation being obtained by the static Repository<T> is in fact TestGenericRepository<T> as we configured in the app.config. I've put the full project for this test application  here: Windsor Repository Test Project.

So what's the benefit of this approach? Well, I'm going to use it to swap out my implementation of a generic Repository so that I can use different ones for my unit tests and my live application while using the same interface throughout my code. All I'll have to do is change a configuration file.