如何以编程方式注册依赖于Castle Windsor已注册组件列表的组件?

Chr*_*ter 3 castle-windsor ioc-container inversion-of-control

我正在以编程方式注册一组服务,这些服务都实现了相同的接口,即IRule.我有另一个服务,看起来像这样:

public class MyService {
    private IEnumerable<IRule> _rules;
    public MyService(IEnumerable<IRule> rules){
        _rules = rules;
    }
}
Run Code Online (Sandbox Code Playgroud)

哈米特发布了一些看起来像我想要的东西,http://hammett.castleproject.org/?p = 257.我将签名更改为IRule []并在帖子中尝试了ArrayResolver技巧,但这对我不起作用(注意,它也没有破坏任何东西).

任何人都知道如何以编程方式注册组件,如上面发布的代码?

Mar*_*ann 6

如果您不想更改MyService的签名并继续使用IEnumerable<IRule>,您还可以创建自定义ISubDependencyResolver.这就是我们所做的:

public class EnumerableResolver : ISubDependencyResolver
{
    private readonly IKernel kernel;

    public EnumerableResolver(IKernel kernel)
    {
        this.kernel = kernel;
    }

    public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
    {
        Type targetType = dependency.TargetType;
        if (targetType == null)
        {
            throw new ArgumentException("TargetType property cannot be null", "dependency");
        }

        if (targetType.IsGenericType && (targetType.GetGenericTypeDefinition() == typeof(IEnumerable<>)))
        {
            Type service = targetType.GetGenericArguments()[0];
            return this.kernel.HasComponent(service);
        }
        return false;
    }

    public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
    {
        Type service = dependency.TargetType.GetGenericArguments()[0];
        Array array = this.kernel.ResolveAll(service, (IDictionary)null);
        return Activator.CreateInstance(typeof(List<>).MakeGenericType(new Type[] { service }), new object[] { array });
    }
}
Run Code Online (Sandbox Code Playgroud)

它需要在容器中注册,如下所示:

container.Kernel.Resolver.AddSubResolver(new EnumerableResolver(this.Kernel));
Run Code Online (Sandbox Code Playgroud)