5

假设我在容器中注册了多个对象,都实现了相同的接口:

container.Register(
    Component.For<ITask>().ImplementedBy<Task1>(),
    Component.For<ITask>().ImplementedBy<Task2>(),
    Component.For<ITask>().ImplementedBy<Task3>(),
    Component.For<ITask>().ImplementedBy<Task4>(),
);

我希望解决 ITask 的所有实现:

var tasks = container.ResolveAll<ITask>();

有没有办法控制已解决实例的顺序?

注意:显然,我可以在 ITask 上实现一个OrderorPriority属性,并且只对任务列表进行排序,但我正在寻找一个较低级别的解决方案。

4

2 回答 2

6

我相信您正在寻找的是一个基于稀缺文档和 Windsor Castle 3 中的重大变化的处理程序过滤器;它提供组件的过滤和排序。这是他们 Wiki 页面的摘录

该接口类似于 IHandlerSelector 但允许您过滤/排序由 container.ResolveAll() 方法请求的处理程序

所以基本上你需要实现IHandlerFilter接口,然后在初始化 Windsor 容器时将此实现添加到内核。从源代码来看,这个界面看起来和这个类似……

public interface IHandlerFilter
{
    bool HasOpinionAbout(Type service);
    IHandler[] SelectHandlers(Type service, IHandler[] handlers);
}

处理程序过滤器添加到内核将如下所示...

 var container = new WindsorContainer()
        .Install(Configuration.FromXmlFile("components.config"));
        container.Kernel.AddHandlersFilter(new YourHandlerFilterImplementation());

然后在使用ResolveAll顺序解析服务的所有组件时,将根据您自己的实现进行排序(和过滤)

于 2014-10-27T08:58:39.477 回答
4

我赞同 Leo 的建议,即您所追求的是处理程序过滤器

在我的博客上,我有一个关于如何制作简单处理程序过滤器的示例,这恰好是在解决它们时ResolveAll<ITask>(或在IEnumerable<ITask>注入时)产生有序任务实例的示例:

class TaskHandlersFilter : IHandlersFilter
{
    readonly Dictionary<Type, int> sortOrder = 
        new Dictionary<Type, int>
        {
            {typeof (PrepareSomething), 1},
            {typeof (CarryItOut), 2},
            {typeof (FinishTheJob), 3},
        };

    public bool HasOpinionAbout(Type service)
    {
        return service == typeof(ITask);
    }

    public IHandler[] SelectHandlers(Type service, IHandler[] handlers)
    {
        // come up with some way of ordering implementations here
        // (cool solution coming up in the next post... ;))
        return handlers
            .OrderBy(h => sortOrder[h.ComponentModel.Implementation])
            .ToArray();
    }
}

我还有一个更详细的示例,它使用用于指定排序的 API - 在这种情况下,我允许类型指定它们相对于另一种类型的位置,例如

[ExecutesBefore(typeof(ExecutePayment))]
public class ValidateCreditCards : ITask { ... }

在您的具体情况下可能/可能没有用:)

于 2014-10-27T09:17:52.853 回答