Skip to content
This repository was archived by the owner on Feb 15, 2023. It is now read-only.

Error: "Request violates the constrain of type TRequest..." on pipelines #91

Open
CheloXL opened this issue Oct 30, 2020 · 8 comments
Open

Comments

@CheloXL
Copy link

CheloXL commented Oct 30, 2020

I just upgraded MediatR and now my project doesn't works as intented.

I have a request AccessTokenAdminCommand : IRequest<OperationResult<string>>. I also have a pipeline defined as PipelineCommands<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IUserIdDescriptor where TResponse : class

Previously, this was working fine (the pipeline was not trying to intercept my command, since AccessTokenAdminCommand doesn't implements IUserIdDescriptor).

Now, MediatR is trying to run the command through the pipeline, throwing:

System.ArgumentException: GenericArguments[0], 'SpiderWeb.CoreService.App.Commands.Commands.Identity.AccessTokenAdminCommand', on 'SpiderWeb.CoreService.Api.PipelineCommands`2[TRequest,TResponse]' violates the constraint of type 'TRequest'.
 ---> System.TypeLoadException: GenericArguments[0], 'SpiderWeb.CoreService.App.Commands.Commands.Identity.AccessTokenAdminCommand', on 'SpiderWeb.CoreService.Api.PipelineCommands`2[TRequest,TResponse]' violates the constraint of type parameter 'TRequest'.
   at System.RuntimeTypeHandle.Instantiate(Type[] inst)
   at System.RuntimeType.MakeGenericType(Type[] instantiation)
   --- End of inner exception stack trace ---
   at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
   at System.RuntimeType.MakeGenericType(Type[] instantiation)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateOpenGeneric(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, Int32 slot)
   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.CallSiteFactory.<>c__DisplayClass7_0.<GetCallSite>b__0(Type type)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.GetCallSite(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 Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at MediatR.ServiceFactoryExtensions.GetInstances[T](ServiceFactory factory)

I'm opening the issue here since this seems to be a problem with the MS DI and the way you find instances of IPipelineBehavior.

@jbogard
Copy link
Owner

jbogard commented Oct 30, 2020

Unless you're on the latest version of MS DI, this won't work. MS DI only with the latest version supports generic constraints

@CheloXL
Copy link
Author

CheloXL commented Oct 30, 2020

I'm running this on an asp.net core 3.1 app. I'm not directly linking MS DI. Also, this was working fine with the previous version of MediatR (v8)...

@jbogard
Copy link
Owner

jbogard commented Oct 30, 2020

Are you using the vanilla container? MS DI would have choked on this every time up until 5.0, this is highly surprising this worked out-of-the-box. I added the PR to MS DI for this exact scenario.

@lilasquared
Copy link

The generic constraints were added for .net 5.0.

It will "work" in previous versions of dotnet core as long as all of your commands sent through the pipeline match the constraint. The moment you try to send a command that violates the constraint you will get this message. Are you sure the exact scenario you are trying worked prior to the MediatR upgrade?

@CheloXL
Copy link
Author

CheloXL commented Oct 30, 2020

Right now I have in front of me a branch of my project with M8 that it is working fine (with the above definitions) and switching to the branch where I upgrade MediatR, I'm getting the above error. So yes, I can confirm that it was working (magically, maybe?) and now it is not.

@jbogard I'm not sure what you mean by vanilla container. I guess the answer is yes, as I'm using the registry container ms provides me in the startup.cs (public void ConfigureServices(IServiceCollection services)).

@lilasquared
Copy link

If you can create a minimal repro of the problem I would be happy to check it out. I have my own test project using M8.1 and I get this exception on dotnet core 3.1 when I have two behaviors registered with exclusive constraints.

@CheloXL
Copy link
Author

CheloXL commented Oct 30, 2020

@lilasquared I will try. Please note that I have only one behavior.

Right now I solved this by removing the constraints and checking for the interface implementation inside the handler.

@lilasquared
Copy link

@CheloXL sorry yeah, one behavior with exclusive constraints.

in my example I have Ping, and Pong and then PingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : Ping

and I get the exception when I attempt to send Pong. This happens with M8.1 and M9.0 on dotnet core 3.1.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants