Autofac 6 - 以其他服务的可用性为条件注册装饰器

Autofac 6 - register decorators conditional on the availability of another service

在 v6 之前,如果我想根据另一个服务的可用性注册装饰器 - 不依赖于应用的其他装饰器 -,我可以这样做:

builder.RegisterType<ApiClientMetricsDecorator>()
       .As(new DecoratorService(typeof(IApiClient)))
       .OnlyIf(b => b.IsRegistered(new TypedService(typeof(IApiCallMetricsReceiver))));

这不再有效。没有应用装饰器。其原因似乎是内部现在新的 v6 中间件机制用于装饰器。

现有的.RegisterDecorator重载只允许传入一个Func<IDecoratorContext, bool>,但是IDecoratorContext不允许我检查服务是否已经注册,它只是为了检查装饰器链和目标实例。

不幸的是,我不能通过复制 RegisterDecorator 的源代码并根据需要进行调整来创建另一个本地扩展方法,因为事实证明类型 DecoratorMiddleware 是内部的。

那么用v6实现我需要的方法是什么?目前我能想到的唯一方法是始终注册装饰器并进行另一次注册:

builder.RegisterType<NullApiCallMetricsReceiver>()
       .As<IApiCallMetricsReceiver>()
       .IfNotRegistered(typeof(IApiCallMetricsReceiver));

但这将是一个非常丑陋的解决方法,因为我会完全不必要地添加一个什么都不做的装饰器。

如果相关的话,我需要这个的原因是因为装饰器的上述注册驻留在一个组件中的一个模块中,该组件正在被不同的项目使用,并且只有 在其中一些,指标是相关的,因此它们注册了一个提供 IApiCallMetricsReceiver.

的类型

我的代码库中多次出现相同的模式。

任何帮助将不胜感激,这目前使我无法升级到 Autofac v6,而且我讨厌不更新核心库,如 Autofac。

这是一个非常好的问题。不幸的是,我认为我不会有一个满意的答案:

在 Autofac v6 中...你不能真正做你想做的事。现在。由于您提到的原因 - 现在不仅仅是关于服务,而是关于管理解析管道。

但是! I have filed an issue on your behalf to get OnlyIf support for decorators in place. We just recently implemented some internals changes 这将允许这种情况发生,所以这是一个很好的时机。

我没有 deadline/ETA 何时交付,但它在雷达上。如果您愿意,可以订阅该问题以进行跟进。