Search code examples
c#dependency-injectioninversion-of-controlcastle-windsor

How do I intercept Castle Windsor's component resolution to override dependencies?


I'm looking for a way to hook into Castle Windsor's resolution process so that I can do something like:

if (componentCanBeResolvedElsewhere)
{
    return elsewhere.Resolve<TService>();
}
else
{
    windsorContainer.Resolve<TService>();
}

I want Castle Windsor to handle the majority of my dependencies, but I want to provide an ability to 'fill-in the blanks'.

I'm sure this can be done, but I'm struggling to find examples.


Solution

  • You can use dependency resolvers which let you declare that you have a special way of solving components. Here is a sample I use to resolve strings from application settings

    public class AppSettingsResolver : ISubDependencyResolver
    {
        public bool CanResolve(
                    CreationContext context,
                    ISubDependencyResolver contextHandlerResolver,
                    ComponentModel model,
                    DependencyModel dependency)
        {
            return !string.IsNullOrEmpty(ConfigurationManager.AppSettings[dependency.DependencyKey])
                   &&
                   TypeDescriptor.GetConverter(dependency.TargetType)
                    .CanConvertFrom(typeof(string));
        }
    
        public object Resolve(
                        CreationContext context,
                        ISubDependencyResolver contextHandlerResolver,
                        ComponentModel model,
                        DependencyModel dependency)
        {
            return TypeDescriptor
                .GetConverter(dependency.TargetType)
                .ConvertFrom(ConfigurationManager.AppSettings[dependency.DependencyKey]);
        }
    }
    

    You then register the resolver in your castle container:

    container.Kernel.Resolver.AddSubResolver(new AppSettingsResolver())