Is order of dependencies guaranteed when injecting IEnumerable<T>

五迷三道 提交于 2019-12-19 05:23:41

问题


I register in container services implementing IMyService.

Do I have any guarantees about their order in

container.Resolve<IEnumerable<IMyService>>

?


回答1:


No, there's no ordering guaranteed here. We've considered extensions to enable it but for now it's something to handle manually.




回答2:


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



回答3:


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.




回答4:


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>>();



回答5:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!