向Rebus

时间:2019-05-31 21:53:22

标签: rebus

发生以下错误:

  

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.ConcurrentDictionary 2.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.

1 个答案:

答案 0 :(得分:0)

该错误来自Microsoft Dependency Injection容器-这是由于您的IErrorHandler实现在其构造函数中使用了IErrorHandler引起的,这似乎并不令人满意。

此特定模式是Decorator pattern,它有助于透明地扩展现有服务的功能。 Rebus鼓励您使用它来扩展其行为,通过向configurer.Decorate<IErrorHandler>(...)注册它,您似乎可以正确地做到这一点。

在这种情况下的错误似乎是您在IoC容器中注册ErrorMessageHandler。 Rebus不会使用您的IoC容器来解析其自己的服务,而仅用于解析消息处理程序。

您的IErrorHandler不是消息处理程序,它是抽象的,它决定了在消息多次失败后Rebus如何处理消息。

因此:不要在您的IoC容器中注册它。