I am trying to implement convention based registration with Castle Windsor, but I cannot figure out how to deal with swapping out default implementations of services.
In my framework, I might have an interface for a service and a default implementation:
public interface ILogger
{
void Info(string message);
}
public class Logger : ILogger
{
public void Info(string message)
{
Console.WriteLine(message);
}
}
In the typical use case, I want Castle Windsor to register Logger with the ILogger service.
However, there are some use cases where the client code might provide an alternate implementation of ILogger:
public class CustomLogger : ILogger
{
public void Info(string message)
{
Console.WriteLine("[LOG]: {0}", message);
}
}
In this use case, I want Castle Windsor to register CustomLogger with the ILogger service instead of Logger.
So far, I've tried something like a tiered approach where I attempt to register all the default interfaces, followed by the non-default interfaces:
using (var container = new WindsorContainer())
{
container.Register(
Classes.FromAssemblyInDirectory(new AssemblyFilter(pluginDirectoryPath))
.Where(type => true)
.WithService.DefaultInterfaces(),
Classes.FromAssemblyInDirectory(new AssemblyFilter(pluginDirectoryPath))
.Where(type => true)
.WithService.AllInterfaces());
var logger = container.Resolve<ILogger>();
logger.Info("hello, world!");
}
However, this doesn't seem to work as both Logger and CustomLogger get registered to ILogger, but I still get back Logger when I resolve ILogger. Any tips for how to do this?
Also, I cannot register each component and service individually as the composition root is its own executable separate from the client code, so it has very limited knowledge of which services are available without doing some assembly scanning.
IsFallback
on the default component; or 2) setting a unique component name and usingIsDefault
for the overrides. See stackoverflow.com/questions/9253388/… – user2864740