发生以下错误:
System.InvalidOperationException HResult = 0x80131509消息= A 检测到类型服务的循环依赖 'Rebus.Retry.IErrorHandler'。 Rebus.Retry.IErrorHandler(Rebus.AzureServiceBus.ErrorMessage.ErrorMessageHandler) -> Rebus.Retry.IErrorHandler Source = Microsoft.Extensions.DependencyInjection StackTrace:在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteChain.CheckCircularDependency(Type serviceType)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType,CallSiteChain(callSiteChain)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType,Type ImplementationType,CallSiteChain,callSiteChain, ParameterInfo []参数,布尔值throwIfCallSiteNotFound)位于 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType,类型ImplementationType,CallSiteChain,callSiteChain)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor 描述符,类型为serviceType,CallSiteChain,callSiteChain) Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType,CallSiteChain(callSiteChain)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType,CallSiteChain(callSiteChain)在 Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.CreateServiceAccessor(Type serviceType)在 System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func
2 valueFactory)位于 Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType,ServiceProviderEngineScope serviceProviderEngineScope)
在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService [T](IServiceProvider 提供者) RebusSubscriber。<> c__DisplayClass7_0`1.b__5(IResolutionContext c)在C:_Repos \ AzureServiceBus \ Subscriber \ RebusSubscriber.cs:第45行 在Rebus.Injection.Injectionist.ResolutionContext.GetTService
以下注册了IErrorHandler
的依赖
services.AddTransient<IErrorHandler, ErrorMessageHandler>();
下面是解决ErrorMessageHandler
并发生上述错误的方法。
Configure.With(Activator)
.Options(o =>
{
o.Decorate<IErrorHandler>(c =>
new ErrorMessageHandler(c.Get<IErrorHandler>()));
}
public class ErrorMessageHandler : IErrorHandler
{
private readonly IErrorHandler _errorHandler;
public ErrorMessageHandler(IErrorHandler errorHandler)
{
_errorHandler = errorHandler;
}
public async Task HandlePoisonMessage(TransportMessage transportMessage, ITransactionContext transactionContext, Exception exception)
{
// keep original behaviour
await _errorHandler.HandlePoisonMessage(transportMessage, transactionContext, exception);
}
}
似乎未使用IResolutionContext会导致错误。
有解决方案吗?
更新
问题是IResolutionContext
需要注册自己的实现而不是自己的IoC。 IErrorHandler
的名称似乎已被滥用。
我的要求是,给定两个单独的组件(Rebus包装器及其客户端),我们需要让Rebus包装器的客户端定义和使用自定义错误处理程序,在这种情况下为ErrorMessageHandler
。
例如,下面的Rebus包装器的伪代码:
Configure.With(Activator)
.Options(o =>
{
//logic to implement below that allow different message handler somehow
//ErrorMessageHandler is this case.
o.Decorate<IErrorHandler>(c =>
xxxxxxx(c.Get<IErrorHandler>()));
}
Rebus包装器的客户端的伪代码:
//pass ErrorMessageHandler to the Rebus wrapper above.
答案 0 :(得分:0)
该错误来自Microsoft Dependency Injection容器-这是由于您的IErrorHandler
实现在其构造函数中使用了IErrorHandler
引起的,这似乎并不令人满意。
此特定模式是Decorator pattern,它有助于透明地扩展现有服务的功能。 Rebus鼓励您使用它来扩展其行为,通过向configurer.Decorate<IErrorHandler>(...)
注册它,您似乎可以正确地做到这一点。
在这种情况下的错误似乎是您在IoC容器中注册ErrorMessageHandler
。 Rebus不会使用您的IoC容器来解析其自己的服务,而仅用于解析消息处理程序。
您的IErrorHandler
不是消息处理程序,它是抽象的,它决定了在消息多次失败后Rebus如何处理消息。
因此:不要在您的IoC容器中注册它。