Error below occurred:
System.InvalidOperationException HResult=0x80131509 Message=A circular dependency was detected for the service of type 'Rebus.Retry.IErrorHandler'. Rebus.Retry.IErrorHandler(Rebus.AzureServiceBus.ErrorMessage.ErrorMessageHandler) -> Rebus.Retry.IErrorHandler Source=Microsoft.Extensions.DependencyInjection StackTrace: at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteChain.CheckCircularDependency(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType, Type implementationType, CallSiteChain callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, CallSiteChain callSiteChain) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.CreateServiceAccessor(Type serviceType) at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func
2 valueFactory) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider) at RebusSubscriber.<>c__DisplayClass7_0`1.b__5(IResolutionContext c) in C:_Repos\AzureServiceBus\Subscriber\RebusSubscriber.cs:line 45 at Rebus.Injection.Injectionist.ResolutionContext.GetTService
Below registers dependency for IErrorHandler
services.AddTransient<IErrorHandler, ErrorMessageHandler>();
Below is how it resolves ErrorMessageHandler
and error above occurred.
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);
}
}
It seems not using IResolutionContext causes the error.
Is there a solution?
Update
The problem is that IResolutionContext
is required to register its own implementation instead of own IoC. It seems the name of IErrorHandler
is overused.
My requirement is, given two separate components (Rebus wrapper, and its client), that we need to let client of rebus wrapper to define and use custom error handler, ErrorMessageHandler
in this case.
For example, the pseudocode of Rebus wrapper below:
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>()));
}
Pseudocode of Client of the Rebus wrapper:
//pass ErrorMessageHandler to the Rebus wrapper above.
The error comes from the Microsoft Dependency Injection container – it's caused by the fact that your IErrorHandler
implementation takes an IErrorHandler
in its constructor, which it doesn't seem to like.
This particular pattern is the Decorator pattern, which helps transparently extend the capabilities of existing services. Rebus encourages you to use it to extend its behavior, which you seem to be doing correctly by registering it with configurer.Decorate<IErrorHandler>(...)
.
The error in this case seems to be that you're registering your ErrorMessageHandler
in your IoC container. Rebus doesn't use your IoC container to resolve its own services, it's ONLY used for resolving message handlers.
Your IErrorHandler
is not a message handler, it's the abstraction that decides how Rebus deals with messages once they have failed too many times.
Therefore: Don't register it in your IoC container.
User contributions licensed under CC BY-SA 3.0