MediatR icon indicating copy to clipboard operation
MediatR copied to clipboard

Pipelines stop working after updating to MediatR 10.0 and .NET 6

Open ShevchukDenys opened this issue 3 years ago • 9 comments

Hi! I have two pipelines behaviours: one with fluent validation and another with logging. So, after updating from MediatR 9.x to 10.0.1 I have faced the following issue: no validation or logging is triggered, in debugging it do not enter none of these classes. The changes I've done:

  1. image
  2. MediatR 9.0.0 => 10.0.1 & .net 5.0 => .net 6.0

ShevchukDenys avatar Feb 02 '22 12:02 ShevchukDenys

Try to isolate this in a test where you resolve from the container directly. The container package version changed too.

jbogard avatar Feb 02 '22 13:02 jbogard

It crashes with 'Sequence containes no elements' if I trying to get IPipelineBehavior or FluentValidationBehhavior directly from container, I suppose it means that this service isn't available in DI. As for container package I have updated it too, just forgot to mention.

ShevchukDenys avatar Feb 04 '22 10:02 ShevchukDenys

Also I have find out that it works if TResult is written explicitly, f.e.: image Looks like it's similar to this: #182

ShevchukDenys avatar Feb 04 '22 12:02 ShevchukDenys

I confirm that, with versions >=10.0, IPipelineBehaviour implementations need the generic constraint added, as per "Migration Guide 9.x to 10.0"

E.g.

public class CanonicalLogLineBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
    //...
}

becomes

public class CanonicalLogLineBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
    where TRequest : IRequest<TResponse>
{
    //...
}

claudioscatoli avatar Feb 17 '22 09:02 claudioscatoli

Hi all! Just wanted to give a +1 to this issue... since the where TRequest : IRequest<TResponse> constraint was added to IPipelineBehavior you can no longer wrap the responses in helper 'Result' classes or interfaces like the OP explained, unless you explicitly register the type... In my case I had:

ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, Result<TResponse>>

and was registering like usual (I'm using Autofac):

services.AddTransient<IPipelineBehavior<,>, ValidationBehavior<,>>();

After upgrading (and adding the constraint to the behavior in question) if I try to resolve IPipelineBehavior<TRequest, Result<TResponse>> directly from the container, it won't resolve. However, built-in behaviors like RequestPreProcessorBehavior, RequestPostProcessorBehavior are resolved correctly as IPipelineBehavior<TRequest, Result<TResponse>>, which I'm guessing has something to do with the calls to ConnectImplementationsToTypesClosing in MediatR.Registration.ServiceRegistrar's AddMediatRClasses method.

Now I'm not sure if this is a DI Container issue or a MediatR issue, since it does resolve if we register a validator for each command or query individually. Any alternatives/tips/workarounds would be great. Staying in v9 for now. Thanks!

rainerllera avatar Mar 14 '22 17:03 rainerllera

@rainerllera I've had the same problem. It could be solved with

class ValidationBehavior<TRequest, TResult> : IPipelineBehavior<TRequest, TResult>>
   where TRequest: IRequest<TResult>

(In this case, TResult corresponds to Result<TResponse> which doesn't appear in the code explicitly but it still works.)

teggno avatar Mar 23 '22 15:03 teggno

I had this for a definition:

public class CacheBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : ICachable

Upgraded to .NET 6 and MediatR 10.0.1 and it won't compile.

Tried changing to :

public class CacheBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<TResponse>

And that doesn't work either - it compiles but fails at runtime. Finally uninstalled 10.0.1 and then regressed back to 9.0.0 and that works with .NET 6, but I don't know what else to do to get this to upgrade to 10.0.1.

Any suggestions would be greatly appreciated.

wehnertb avatar Jun 01 '22 21:06 wehnertb

Looks like you'd need two constraints:

public class CacheBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<TResponse>, ICachable

That compiles for me fine.

jbogard avatar Jun 01 '22 21:06 jbogard

Thanks - that fixed it!

wehnertb avatar Jun 02 '22 16:06 wehnertb

DO we need to add this where condition: [where TRequest: IRequest<TResult>]

It's working for me without the where for me.

plppp2001 avatar Feb 15 '24 23:02 plppp2001