Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,026 | Comments: 44,842

filter by tags archive

Envrionment Validation and Windsor Extensibility

time to read 5 min | 901 words

So I was in Jermey Miller's talk about maintainable software echo system, and one of the thing that he mentioned that StructureMap does really well is the ability to ask the container to perform envrionment validations, to make sure that the envrionment is ready for us.

I really liked the idea, so I pulled up the laptop and started spiking how to handle this issue. First, let us see Jeremy's solution:

public class FileTextReader : ITextReader
	public void ValidateFileExistance()
		if (File.Exists(fileName) == false)
			throw new FileNotFoundException("Could not find file " + fileName);

So, when you ask structure map to validate the environment, it will run all the methods that have been decorated with [ValidateConfiguration].

So, how do that that in Windsor?

The most important thing to realize with Windsor is that it is a container that was built to be extensible. Something like that is not going to be a change to the container, it will be an extension, not a change to the container itself. Extensions are usually facilities, like this one:

public class ValidationFacility : AbstractFacility
	private readonly List<string> componentsToValidate = new List<string>();

	protected override void Init()
		IHandler handler = Kernel.GetHandler(typeof(ValidateConfiguration));
		Kernel.ComponentRegistered += OnComponentRegistered;

	public void OnComponentRegistered(string key, IHandler handler)
		foreach (MethodInfo method in 
handler.ComponentModel.Implementation.GetMethods()) { bool isValidateMethod = method
.GetCustomAttributes(typeof(ValidateConfigurationAttribute), true)
.Length != 0; if (isValidateMethod) { componentsToValidate.Add(key); break; } } } }

This extends the container, and whenever a component is registered, I am checking if I need to add that to the list of components that needs validation. I am doing a  tiny bit of cheating here and passing the componentsToValidate as a reference to the component, it is simpler that way, but the component gets the same instance, which is probably not what I would like to do with it for other approaches. I would usually got with a sub resolver that matched that issue, if I was doing something like this for more interesting purposes.

Anyway, here how the ValidationConfiguration class is built:

public class ValidateConfiguration
	private readonly ICollection<string> componentsToValidate;
	private readonly ILogger logger;
	private readonly IKernel kernel;

	public ValidateConfiguration(
		ICollection<string> componentsToValidate,
		ILogger logger,
		IKernel kernel)
		this.componentsToValidate = componentsToValidate;
		this.logger = logger;
		this.kernel = kernel;

	public void PerformValidation()
		foreach (string key in componentsToValidate)

	private void ValidateComponent(string key)
		IHandler handler = kernel.GetHandler(key);
		if (handler == null)
			logger.Warn("Component {0} was removed before it could be validated", key);
			object component = handler.Resolve(CreationContext.Empty);
			foreach (MethodInfo method in component.GetType().GetMethods())
				bool isValidateMethod = method.GetCustomAttributes(typeof(ValidateConfiguration), true).Length == 0;
				if (isValidateMethod)
					ExecuteValidationMethod(component, method);
		catch (TargetInvocationException e)
			logger.Error("Failed to run validation for {0}, because: {1}", key, e.InnerException);
		catch (Exception e)
			logger.Error("Failed to run validation for {0}, because: {1}", key, e);

	private void ExecuteValidationMethod(object component, MethodBase method)
			method.Invoke(component, new object[0]);
		catch (Exception e)
			logger.Error("Failed to validate {0}.{1}. Error: {2}",

This is a class that has some deep association with the container. It is usually not something that I would like in my application services, but it is fine for instrastracture pieces, like this one.

Now that I have that , I can actually test the implementation:

IWindsorContainer container = new WindsorContainer();
container.AddFacility("validation", new ValidationFacility());
container.AddComponent<ITextReader, FileTextReader>();
	.AddCustomDependencyValue("fileName", "foo");
container.AddComponent<ILogger, ConsoleLogger>();

ValidateConfiguration resolve = container.Resolve<ValidateConfiguration>();

And this will go over everything and perform whatever validations needs to be done.

As I said, I really like the idea, and extending this to a build task is really trivial (especially if you are using Boo Build System to do things).

The main point, however, is that I managed to write this piece of code (around 100 lines or so), during Jeremy's talk, so from the time he talked about that feature to the time that he finished, I already got that done. This actually has nothing to do with my personal prowess with code, but it has a lot to do with the way Windsor it built, as a set of services that can be so readily extended.

After I have gotten used to the style that Windsor has, it is getting really addictively easy to start extending the container in interesting ways. I highly recommend that you will take a look at those features, they are interesting both from "what I can do with them" and from "what design allowed this".



That is a neat little thing. Not sure I can use it at the moment, but always nice to have a tool in the box when you need it!


The extensibility of Windsor is really great. I extended it to allow for dynamic component selection (based on current user type) with very few lines of code and it removed the need for many otherwise necessary factories.


Cool ! Btw, I think you can reduce a little more your code by using


instead of GetCustomAttributes(..).Length != 0

Just me nitpicking, as usual....


I started to write facilities soon after starting to use the Windsor container in my projects. It's really easy to do and has provided me with some real benefits!

Comment preview

Comments have been closed on this topic.


No future posts left, oh my!


  1. Technical observations from my wife (3):
    13 Nov 2015 - Production issues
  2. Production postmortem (13):
    13 Nov 2015 - The case of the “it is slow on that machine (only)”
  3. Speaking (5):
    09 Nov 2015 - Community talk in Kiev, Ukraine–What does it take to be a good developer
  4. Find the bug (5):
    11 Sep 2015 - The concurrent memory buster
  5. Buffer allocation strategies (3):
    09 Sep 2015 - Bad usage patterns
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats