Castle.Windsor CollectionResolver和组件排序

时间:2014-03-14 13:04:07

标签: c# .net inversion-of-control castle-windsor

我们使用Castle.Windsor(3.1)中的CollectionResolver来注入一组组件。这些顺序是相关的。目前,我们在服务上使用Position属性来订购它们。

由于我们在具有不同组件的不同应用程序中使用相同的主组件,因此position属性是一种维护负担。它意味着彼此了解组件。单个组件也不应该了解其他组件。

我们希望为特定服务类型注册多个IComparer<Type>,以控制注入组件的顺序。

有没有一种简单的(预定义的)方法可以在Castle.Windsor中执行此操作,或者之前有人这样做过吗?

我们想要替换的例子:

interface IService
{
   bool Do();
   int Position { get; } // <= This should be kicked!
}

class Master
{
   private readonly IService[] _services;

   public Master(IService[] services)
   {
       // Master should not care about ordering also,
       // but injecting a sorter would be acceptable
       _services = services.OrderBy(s => s.Position).ToArray();
   }

   public void Do()
   {
       foreach(var service in _services)
       {
          if(!service.Do())
             break;
       }
    }
}

我们想要像上面这样没有使用像这样的组件的位置:

class OrderService : IComparer<Type>
{       
   public int Compare(Type x, Type y)
   {
      if(typeof(MoreImportantComponent) == x)
         return -1;
      else
         return 0;

   }
}

1 个答案:

答案 0 :(得分:1)

您可以使用IHandlersFilter实施

来影响服务的顺序
public class ServiceHandlersFilter : IHandlersFilter
{
    private readonly List<Type> sortOrder = new List<Type>
                                                {
                                                   { typeof(Service1) },
                                                   { typeof(Service2) },
                                                   { typeof(Service3) },
                                                };

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

    public IHandler[] SelectHandlers(Type service, IHandler[] handlers)
    {
        return handlers
            .OrderBy(h => sortOrder.IndexOf(h.ComponentModel.Implementation))
            .ToArray();
    }
}

您可能希望更优雅地确定排序顺序,例如,组件本身。如果是这种情况,请查看此RespectOrderDirectivesHandlersFilter实施。在过滤器上As per mookid's blog post,您可以将IService实施与ExecutesBeforeAttributeExecutesAfterAttribute属性相关联,以暗示相对于彼此的执行顺序。