由于您表明您正在使用GetAllInstances
,我怀疑您使用了一个RegisterManyForOpenGeneric
接受回调委托的重载,如下所示:
container.RegisterManyForOpenGeneric(
typeof(ISubstriber<>),
(type, impls) => container.RegisterAll(type, impls),
typeof(ISubstriber<>).Assembly);
在这种情况下,将实现列表提供给委托的顺序取决于它们从 .NET 元数据返回的顺序。RegisterManyForOpenGeneric
只需调用GetExportedTypes()
提供的程序集。返回这些类型的顺序非常不可靠,并且在未来的 C# 版本中甚至可能通过重新编译代码和在未来的 CLR 版本中仅通过重新启动应用程序来更改。
因此,如果实现必须按特定顺序放置在列表中,您所要做的就是对实现列表进行排序:
(serviceType, impls) => container.RegisterAll(serviceType,
impls.OrderBy(type => [some condition]));
但是,总的来说,我会说事情的顺序无关紧要。如果它们确实重要,请仔细查看您的设计。这里可能存在一些问题。例如,您想用[SubscriberPriority]
属性标记某些类的事实表明您可能缺少抽象。也许您应该给他们自己的界面并单独注册。
我总是建议做的另一件事是通过将注册列表放在复合后面来隐藏应用程序的注册列表:
public class CompositeSubscriber<T> : ISubscriber<T>
{
private IEnumerable<ISubscriber<T>> subscribers;
public CompositeSubscriber(
IEnumerable<ISubstriber<T>> subscribers)
{
this.subscribers = subscribers;
}
public void Handle(T value)
{
foreach (var subscriber in this.subscribers)
{
subscriber.Handle(value);
}
}
}
该复合材料可以按如下方式注册:
container.RegisterSingleOpenGeneric(typeof(ISubscriber<>),
typeof(CompositeSubscriber<>);
这种情况下,应用程序可以简单地依赖ISubscriber<T>
而不是IEnumerable<ISubscriber<T>>
. RegisterManyForOpenGeneric
现在您可以使用组合来控制顺序,而不是使用方法的回调来控制顺序。