注入 IEnumerable时是否保证依赖关系的顺序?

发布于 2024-10-20 16:07:44 字数 145 浏览 4 评论 0原文

我在实现 IMyService 的容器服务中注册。

我对他们的订单有任何保证吗

container.Resolve<IEnumerable<IMyService>>

I register in container services implementing IMyService.

Do I have any guarantees about their order in

container.Resolve<IEnumerable<IMyService>>

?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

2024-10-27 16:07:44

正如为像我这样登陆此页面的人提供额外帮助...这是一个如何做到这一点的示例。

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

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;
    }
  }
终遇你 2024-10-27 16:07:44

不,这里不保证订购。我们已经考虑过通过扩展来启用它,但目前需要手动处理。

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

愿与i 2024-10-27 16:07:44

我并不是要自我推销,但我也创建了一个包来解决这个问题,因为我有类似的需求: https://github.com/mthamil/Autofac.Extras.Ordering

它使用 IOrderedEnumerable接口来声明是否需要订购。

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.

错爱 2024-10-27 16:07:44

我知道这是一篇旧文章,但为了维持注册顺序,我们不能在注册过程中使用 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<IEnumerable<IService>>();

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<IEnumerable<IService>>();
风筝在阴天搁浅。 2024-10-27 16:07:44

我没有找到有关该主题的任何新信息,并编写了一个测试,该测试非常简单(您最好自己编写):

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) 中,顺序被明智地保留。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文