I register in container services implementing IMyService.
Do I have any guarantees about their order in
container.Resolve<IEnumerable<IMyService>>
?
No, there's no ordering guaranteed here. We've considered extensions to enable it but for now it's something to handle manually.
Just as extra help for people like me landing on this page... Here is an example how one could do it.
public static class AutofacExtensions
{
private const string OrderString = "WithOrderTag";
private static int OrderCounter;
public static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
WithOrder<TLimit, TActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> registrationBuilder)
{
return registrationBuilder.WithMetadata(OrderString, Interlocked.Increment(ref OrderCounter));
}
public static IEnumerable<TComponent> ResolveOrdered<TComponent>(this IComponentContext context)
{
return from m in context.Resolve<IEnumerable<Meta<TComponent>>>()
orderby m.Metadata[OrderString]
select m.Value;
}
}
I don't mean to self-promote, but I have also created a package to solve this problem because I had a similar need: https://github.com/mthamil/Autofac.Extras.Ordering
It uses the IOrderedEnumerable<T> interface to declare the need for ordering.
I know this is an old post but to maintain the order of registration, can't we just use PreserveExistingDefaults() during registration?
builder.RegisterInstance(serviceInstance1).As<IService>().PreserveExistingDefaults();
builder.RegisterInstance(serviceInstance2).As<IService>().PreserveExistingDefaults();
// services should be in the same order of registration
var services = builder.Resolve<IEnumberable<IService>>();
I didn't find any fresh information on topic and wrote a test which is as simple as (you'd better write your own):
var cb = new ContainerBuilder();
cb.RegisterType<MyClass1>().As<IInterface>();
// ...
using (var c = cb.Build())
{
using (var l = c.BeginLifetimeScope())
{
var e = l.Resolve<IEnumerable<IInterface>>().ToArray();
var c = l.Resolve<IReadOnlyCollection<IInterface>>();
var l = l.Resolve<IReadOnlyList<IInterface>>();
// check here, ordering is ok
}
}
Ordering was kept for all cases I've come up with. I know it is not reliable, but I think that in the current version of Autofac (4.6.0) ordering is wisely kept.
来源:https://stackoverflow.com/questions/5218803/is-order-of-dependencies-guaranteed-when-injecting-ienumerablet