Search code examples
inversion-of-controlcastle-windsorioc-containerdependency-inversion

Resolve Castle Windsor dependency by argument name


Given That

Component.For<IService>().ImplementedBy<SecretService>().Named("secretService")
Component.For<IService>().ImplementedBy<PublicService>().Named("publicService")

And

class Foo{
    public Foo(IService publicService){ ...... }
}

And

class Bar{
    public Bar(IService secretService){ ...... }
}

Then how can i achieve the following

Foo and Bar should get instances of publicService and secretService respectively, entirely based on name of their constructor parameters.


Solution

  • I have now made it to work using a custom SubDependencyResolver, i added this to the container and now it injects the implementation by name

    public class ByParameterNameResolver : ISubDependencyResolver
    {
        private readonly IKernel kernel;
    
        public ByParameterNameResolver(IKernel kernel)
        {
            this.kernel = kernel;
        }
    
        public virtual bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
        {
            if (dependency.TargetItemType == null)
                return false;
    
            if (string.IsNullOrWhiteSpace(dependency.DependencyKey))
                return false;
    
            return kernel.HasComponent(dependency.DependencyKey);
        }
    
        public virtual object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
        {
            return kernel.Resolve(dependency.DependencyKey, dependency.TargetItemType);
        }
    }