我们使用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;
}
}
答案 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
实施与ExecutesBeforeAttribute
和ExecutesAfterAttribute
属性相关联,以暗示相对于彼此的执行顺序。