jbogard / MediatR

Simple, unambitious mediator implementation in .NET
Apache License 2.0
10.91k stars 1.16k forks source link

IRequestPreProcessor & IRequestPostProcessor not trigging on MediatR 12.1.0 #924

Closed xts-velkumars closed 1 year ago

xts-velkumars commented 1 year ago

@jbogard,

My PreProcessor & PostProcessor is not getting triggered after I update to MediatR 12.1.0.

What could cause this? How do I resolve this?

jbogard commented 1 year ago

After upgrading from what previous version?

xts-velkumars commented 1 year ago

12.0.1 to 12.1.0

This how I have injected. With 12.0.1 I don't have any issues.

image

darjanbogdan commented 1 year ago

It doesn't seem you have registered RequestPreProcessorBehavior.cs and RequestPostProcessorBehavior.cs. That is mandatory in order to trigger your own post/pre processors.

Soundman32 commented 1 year ago

@xts-velkumars Is it also possible that your handlers implement IRequestHandler and not IRequestHandler<TRequest, TResponse> ? I found out today that behaviours aren't supported for the former: https://github.com/jbogard/MediatR/wiki/Behaviors#nb

jbogard commented 1 year ago

@xts-velkumars Is it also possible that your handlers implement IRequestHandler and not IRequestHandler<TRequest, TResponse> ? I found out today that behaviours aren't supported for the former: https://github.com/jbogard/MediatR/wiki/Behaviors#nb

This is incorrect, the docs say it's not compatible with INotificationHandler<T>. It works just fine with IRequestHandler<TRequest>.

jbogard commented 1 year ago

From the upgrade guide, MediatR no longer scans for pre/post processors. This is because order often matters with those, and it's not possible to order them if they're automatically registered. You'll need to call the appropriate AddRequestPre/PostProcessor methods.

Also, I would move your behavior registration to use AddBehavior inside of AddMediatR to be consistent.

Soundman32 commented 1 year ago

Sorry, my bad. I've been trying to get a pipeline working with IRequestHandler<TRequest> all morning, and didn't work. I assumed it's the same thing.

(BTW I've updated my behaviour to a IRequestPreProcessor<TRequest> and it's now working for me.)

xts-velkumars commented 1 year ago

Do you have any examples for this ?

xts-velkumars commented 1 year ago

It doesn't seem you have registered RequestPreProcessorBehavior.cs and RequestPostProcessorBehavior.cs. That is mandatory in order to trigger your own post/pre processors.

How do I register this?

jbogard commented 1 year ago

You don't register those behaviors yourself. Those two behaviors get registered automatically when you add pre/post processors like:

services.AddMediatR(cfg =>                                                                       
{                                                                                                
    cfg.RegisterServicesFromAssembly(typeof(Ping).Assembly);
    cfg.AddOpenBehavior(typeof(OuterBehavior<,>));
    cfg.AddOpenBehavior(typeof(InnerBehavior<,>));                                     
    cfg.AddRequestPreProcessor<IRequestPreProcessor<Ping>, FirstConcretePreProcessor>();         
    cfg.AddRequestPreProcessor<IRequestPreProcessor<Ping>, NextConcretePreProcessor>();          
    cfg.AddOpenRequestPreProcessor(typeof(FirstPreProcessor<>));                                 
    cfg.AddOpenRequestPreProcessor(typeof(NextPreProcessor<>));                                  
    cfg.AddRequestPostProcessor<IRequestPostProcessor<Ping, Pong>, FirstConcretePostProcessor>();
    cfg.AddRequestPostProcessor<IRequestPostProcessor<Ping, Pong>, NextConcretePostProcessor>(); 
    cfg.AddOpenRequestPostProcessor(typeof(FirstPostProcessor<,>));                              
    cfg.AddOpenRequestPostProcessor(typeof(NextPostProcessor<,>));                               
});                                                                                              

There are now methods for anything that requires a specific order, in the form of:

cfg.AddOpenXYZ(typeof(ABC<>)); // this is for open generics
cfg.AddXYZ(typeof(DEF)); // this is for closed generics, the service type is inferred from the implementation type
cfg.AddXYZ(typeof(IXyz<Foo, Bar>), typeof(GHI)); // this is for closed generics with the explicit service type defined