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



在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中…你不能真正做你想做的事。马上由于您提到的原因,现在不仅仅是服务,而是管理解决管道。

但是!我已经代表您提交了一个问题,以获得对装饰器的OnlyIf支持。我们最近刚刚实现了一些内部更改,可以实现这一点,所以这是一个很好的时机。

我没有关于何时交付的最后期限/预计到达时间,但它已经在雷达上了。如果你喜欢的话,你可以订阅这期杂志。

最新更新