简体   繁体   English

在温莎城堡致电ResolveAll时订购

[英]Order when calling ResolveAll in Castle Windsor

Assume that I have multiple objects registered in the container, all implementing the same interface: 假设我在容器中注册了多个对象,都实现了相同的接口:

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

And I wish to resolve all the implementations of ITask: 我希望解决ITask的所有实现:

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

Is there a way to control the order of the resolved instances? 有没有办法控制已解析实例的顺序?

Note: Obviously, I can implement an Order or Priority property on ITask, and just sort the list of tasks, but I am looking for a lower-level solution. 注意:显然,我可以在ITask上实现OrderPriority属性,只是对任务列表进行排序,但我正在寻找更低级别的解决方案。

I believe that what you are looking for is a Handler Filter which based on the scarce documentation and the breaking changes in Windsor Castle 3; 我相信你正在寻找的是一个Handler过滤器 ,它基于稀少的文档和Windsor Castle 3中的重大变化; it provides filtering and sorting of components. 它提供组件的过滤和排序。 Here's an extract from their Wiki page 这是他们的Wiki页面的摘录

The interface is similar to IHandlerSelector but allow you to filter/sort handlers requested by container.ResolveAll() method 该接口类似于IHandlerSelector,但允许您过滤/排序container.ResolveAll()方法请求的处理程序

So basically you will need to implement the IHandlerFilter interface and then add this implementation to the kernel while initializing the Windsor container. 所以基本上你需要实现IHandlerFilter接口,然后在初始化Windsor容器时将此实现添加到内核中。 From the source code , this interface looks something similar to this... 源代码中 ,这个界面看起来与此类似......

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

Adding the Handler Filter to the kernel would be something like below... 处理程序过滤器添加到内核将如下所示......

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

and then when resolving all components of a services with ResolveAll the order will be sorted (and filtered) based on your own implementation 然后,当使用ResolveAll解析服务的所有组件时,将根据您自己的实现对订单进行排序(和过滤)

I second Leo's advice that what you're after is a handlers filter . 我是Leo的第二个建议,你所追求的是一个处理程序过滤器

On my blog I have this example on how a simple handlers filter can be made , which happens to be one that results in ordered task instances when they're resolved through ResolveAll<ITask> (or when an IEnumerable<ITask> gets injected): 在我的博客上,我有一个关于如何 ResolveAll<ITask> 一个简单的处理程序过滤器的例子 ,恰好是当它们通过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();
    }
}

I also have a more elaborate example that plays around with the API used to specify the ordering - in this case, I'm allowing for the types to specify their position relative to another type, eg like 我还有一个更详细的例子 ,用于指定排序的API - 在这种情况下,我允许类型指定相对于另一种类型的位置,例如像

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

which might/might not be useful in your concrete situation :) 哪些可能/可能没有用在你的具体情况:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM