Rejestruję się w usługach kontenerowych implementujących IMyService.Czy kolejność zależności jest zagwarantowana podczas wstrzykiwania IEnumerable <T>
Czy mam żadnych gwarancji co do ich kolejności
container.Resolve<IEnumerable<IMyService>>
?
Rejestruję się w usługach kontenerowych implementujących IMyService.Czy kolejność zależności jest zagwarantowana podczas wstrzykiwania IEnumerable <T>
Czy mam żadnych gwarancji co do ich kolejności
container.Resolve<IEnumerable<IMyService>>
?
Nie, tutaj nie ma zagwarantowanego zamówienia. Rozważaliśmy rozszerzenia, aby je włączyć, ale na razie jest to coś, z czym trzeba sobie poradzić ręcznie.
Tak samo jak dodatkowa pomoc dla osób takich jak ja lądujących na tej stronie ... Oto przykład, jak można to zrobić.
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;
}
}
Co jeśli chcesz wstrzyknąć już zamówione? –
Nie mówię do siebie promować, ale także stworzył pakiet, aby rozwiązać ten problem, bo miałem podobną potrzebę: https://github.com/mthamil/Autofac.Extras.Ordering
Używa IOrderedEnumerable < T> Interfejs zadeklarować potrzeba zamawiania.
Czy działa również z rejestracją? –
Wiem, że to stary post, ale aby zachować kolejność rejestracji, nie możemy po prostu użyć PreserveExistingDefaults() podczas rejestracji?
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>>();
Nie sądzę, że ** PreserveExistingDefaults ** ma jakiekolwiek gwarancje na ** IEnumerable
Nie znalazłem żadnej dokumentacji na ten temat, ale z testów jednostkowych, które napisałem przeciwko niemu, one przemijają. Obecnie używam go do mojej aplikacji, a wyniki są spójne. –
Nie mogę znaleźć żadnych informacji na temat świeżych i napisali test, który jest tak proste, jak (lepiej napisać własne):
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
}
}
Kolejność była przetrzymywana przez wszystkich przypadkach ja wymyśliłem. Wiem, że to nie jest niezawodne, ale myślę, że w obecnej wersji Autofac (4.6.0) porządek jest mądrze utrzymany.
Jakie jest zatem najlepsze rozwiązanie? Czy powinienem dodać metadane w "Priorytecie" i zamówić przez niego? –
To brzmi jak dobra opcja. –