I'm trying to define essentially a catch-all request exception handler independent of message types, something like this:
public class GenericExceptionHandler<TRequest, TResponse> : IRequestExceptionHandler<TRequest, TResponse>
However, MS DI throws when MediatR is trying to get errors handlers:
System.ArgumentException: The number of generic arguments provided doesn't equal the arity of the generic type definition.
Parameter name: instantiation
at System.RuntimeType.MakeGenericType(Type[] instantiation)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateOpenGeneric(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateEnumerable(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.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at MediatR.Pipeline.RequestExceptionProcessorBehavior`2.GetExceptionHandlers(TRequest request, Type exceptionType, MethodInfo& handleMethodInfo)
at MediatR.Pipeline.RequestExceptionProcessorBehavior`2.<Handle>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.<Handle>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.<Handle>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MediatR.Pipeline.RequestPostProcessorBehavior`2.<Handle>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MediatR.Pipeline.RequestPreProcessorBehavior`2.<Handle>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at MediatR.Extensions.Microsoft.DependencyInjection.Tests.PipelineTests.<>c__DisplayClass23_0.<<Should_pick_up_base_exception_behaviors>b__0>d.MoveNext() in C:\p\sym\MediatR.Extensions.Microsoft.DependencyInjection\test\MediatR.Extensions.Microsoft.DependencyInjection.Tests\PipelineTests.cs:line 457
at Shouldly.Should.CompleteIn(Task actual, TimeSpan timeout, Func`1 customMessage, String what)
at Shouldly.Should.CompleteIn(Task actual, TimeSpan timeout, Func`1 customMessage)
at Shouldly.Should.RunAndWait(Func`1 actual, TimeSpan timeoutAfter, Func`1 customMessage)
at Shouldly.Should.ThrowInternal[TException](Func`1 actual, TimeSpan timeoutAfter, Func`1 customMessage, String shouldlyMethod)
The only way to make it work that I found is to have the handler explicitly define the third generic parameter.
This works:
public class GenericExceptionHandler<TRequest, TResponse, TException> : IRequestExceptionHandler<TRequest, TResponse, TException> where TException : Exception
These don't:
public class GenericExceptionHandler<TRequest, TResponse> : IRequestExceptionHandler<TRequest, TResponse, Exception>
public class GenericExceptionHandler<TRequest, TResponse> : IRequestExceptionHandler<TRequest, TResponse>
Perhaps this is a limitation of MS DI, but at least MediatR makes this partially closed interface available IRequestExceptionHandler<TRequest, TResponse> so it is still possible to shoot oneself in the foot.
Perhaps I'm doing something wrong?
I'm trying to define essentially a catch-all request exception handler independent of message types, something like this:
However, MS DI throws when MediatR is trying to get errors handlers:
The only way to make it work that I found is to have the handler explicitly define the third generic parameter.
This works:
These don't:
Perhaps this is a limitation of MS DI, but at least MediatR makes this partially closed interface available
IRequestExceptionHandler<TRequest, TResponse>
so it is still possible to shoot oneself in the foot. Perhaps I'm doing something wrong?