Mr Andersson

Switching component implementations in Castle Windsor

leave a comment »

Problem: Test suite for a system for which I need to replace (inject) the behavior of a certain component. The system is using Castle Windsor with an XML configuration file.

In this system integration test I want to use the real container configuration except that I want to switch out a component that does authorization using a database.

The replacement for the real component is as simple as:

public bool IUsernamePasswordVerifier.VerifyPasswordFor( string username, string password )
return true;
Solution: Tried this, which failed on me. But with a little help from a tiny facility used by the test suite I can now “re-wire” service implementations in the container.
There are probably several other solutions on how one could accomplish the same thing, but this one worked out very well for me.


using System;
using System.Collections.Generic;
using Castle.Core;
using Castle.Core.Configuration;
using Castle.MicroKernel;

namespace ServiceTests.Service
public class ComponentRewriteFacility : IFacility
readonly IDictionary<Type, Type> _rewrites;

public ComponentRewriteFacility()
_rewrites = new Dictionary<Type, Type>();

public void AddRewrite<I, T>() where T : I
_rewrites.Add( typeof(I), typeof(T) );

public virtual void Init( IKernel kernel, IConfiguration facilityConfig )
if( kernel == null )
throw new ArgumentNullException( "kernel" );
kernel.ComponentRegistered += ComponentRegistered;

public void Terminate()

void ComponentRegistered( string key, IHandler handler )
if( !ShouldRewrite( handler.ComponentModel ) )
handler.ComponentModel.Implementation = _rewrites[handler.ComponentModel.Service];

protected virtual bool ShouldRewrite( ComponentModel componentModel )
return _rewrites.ContainsKey( componentModel.Service );

And in our test suite initializer we add the “re-write rule” like this:

IWindsorContainer container = new WindsorContainer();
container.AddFacility<ComponentRewriteFacility>( f => f.AddRewrite<IUsernamePasswordVerifier, AnythingGoesUsernamePasswordVerifier>() );
container.Install( Castle.Windsor.Installer.Configuration.FromXmlFile( "Windsor.xml" ) );

Like it? Not? Have a better solution? Please let me know!

Written by anderssonjohan

October 28, 2009 at 19:34

Posted in programming

Tagged with , , , ,

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: