Гарантирован ли порядок зависимостей при внедрении IEnumerable <T> - PullRequest
10 голосов
/ 07 марта 2011

Я регистрируюсь в контейнерных сервисах, реализующих IMyService.

Есть ли у меня какие-либо гарантии по поводу их заказа в

container.Resolve<IEnumerable<IMyService>>

Ответы [ 5 ]

11 голосов
/ 22 декабря 2011

Так же, как дополнительная помощь для людей вроде меня, попадающих на эту страницу ... Вот пример, как можно это сделать.

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;
    }
  }
7 голосов
/ 08 марта 2011

Нет, заказ здесь не гарантирован.Мы рассмотрели расширения, чтобы включить его, но сейчас это что-то, что нужно обрабатывать вручную.

4 голосов
/ 04 января 2015

Я не имею в виду саморекламу, но я также создал пакет для решения этой проблемы, потому что у меня была похожая потребность: https://github.com/mthamil/Autofac.Extras.Ordering

Он использует интерфейс IOrderedEnumerable для объявлениянеобходимость заказа.

1 голос
/ 25 апреля 2015

Я знаю, что это старый пост, но для поддержания порядка регистрации, мы не можем просто использовать PreserveExistingDefaults () при регистрации?

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>>();
0 голосов
/ 28 июня 2017

Я не нашел свежей информации по теме и написал такой простой тест, как (лучше написать свой):

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
    }
}

Заказ был сохранен во всех случаях, которые япридумать.Я знаю, что это ненадежно, но я думаю, что в текущей версии Autofac (4.6.0) порядок разумно сохраняется.

...