In the last post we have deeply analyzed the problem and we have seen the high level solution we adopted:

container.Register
(
	Component.For<ISecurityService>()
		.ImplementedBy<DefaultSecurityService>()
		.Overridable()
);

First of all, Castle Windsor has the ability to remove a registration from the dependency graph but we cannot use that feature when we do not know the order in which components arte registered and at the end of the registration process that feature, obviously, does not work any more since the component we are trying to remove can have dependencies on other components, and so on...

So far…not so good…

We have to find another way to achieve the goal, basically we can say:

  • register all what you want;
  • mark something as “overridable”;
  • at resolve time:
    • if there are 2 components that satisfies the request and one is marked as “overridable”:
      • use the other one;
    • otherwise let Castle take a decision;

Please welcome the “NamingSubsystem”

Castle has tons of extension points, so many that sometimes it is difficult to understand which one is the right one, in this specific case one really good candidate is the NamingSubsystem that is responsible, well can be, to choose which handler should be used to resolve a dependency.

In our scenario I’ve setup a DelegateNamingSubSystem (that can be found on NuGet):

var nss = new DelegateNamingSubSystem()
{
	SubSystemHandler = ( s, hs ) =>
	{
		if( hs.Any( h => h.ComponentModel.IsOverridable() ) )
		{
			var nonOverridable = hs.Except( hs.Where( h => h.ComponentModel.IsOverridable() ) );
			if( nonOverridable.Any() )
			{
				return nonOverridable.Single();
			}
		}
 
		return null;
	}
};

This naming sub system simply delegates the problem to the end user code, in which we simply say:

if in the handler list (hs) there is any handler whose component model is marked as overridable choose the other one, trivial, otherwise return null so to let Castle take a decision.

Registering a naming sub system is a really easy operation:

var container = new Castle.Windsor.WindsorContainer();
container.Kernel.AddSubSystem( SubSystemConstants.NamingKey, nss );

Wait a minute!

How does the “Overridable” and “IsOverridable” extension methods work?

Overridable:

public static ComponentRegistration<T> Overridable<T>( this ComponentRegistration<T> registration )
{
	registration.ExtendedProperties
	(  Property.ForKey( OVERRIDABLE_OVERRIDABLE_REGISTRATION )
			.Eq( true )  );
			
	return registration;
}

IsOverridable:

public static Boolean IsOverridable( this ComponentModel componentModel )
{
	return componentModel.ExtendedProperties.Contains( OVERRIDABLE_OVERRIDABLE_REGISTRATION );
}

Nothing special, nothing… only frictionless Smile

.m