Lincoln Teixeira
Lincoln Teixeira

Reputation: 165

MediatR Multiple Pipeline Behaviors

Hello I already use this pattern of Mediator CQRS with Pipeline Behavior for a while, but just now I'm facing a issue where the generic implementation of TResponse and TRequest are not enough. So I'm trying to understand if having two separate pipelines for two very specific request is a bad practice or a bad idea.

So the main idea is, having a PipelineBehavior<RequestOne, ResponseOne> to do a specific logic for the requestOne, and another PipelineBehavior<RequestTwo, ResponseTwo> to do another logic that doesn't apply to request one.

Upvotes: 6

Views: 4384

Answers (3)

lonix
lonix

Reputation: 20499

You can construct multiple pipelines with different behaviors.

Register pipeline behaviors:

// pipeline 1's behaviors
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(FooBehavior<,>));
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(BarBehavior<,>));
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(BazBehavior<,>));

// pipeline 2's behaviors
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(CatBehavior<,>));
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(DogBehavior<,>));
services.AddScoped(typeof(IPipelineBehavior<,>), typeof(PigBehavior<,>));

Define pipelines:

// pipeline 1
public interface IPipeline1 { }
public class FooBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IPipeline1 { }
public class BarBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IPipeline1 { }
public class BazBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IPipeline1 { }

// pipeline 2
public interface IPipeline2 { }
public class CatBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IPipeline2 { }
public class DogBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IPipeline2 { }
public class PigBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IPipeline2 { }

Define requests:

// requests to be processed by pipeline 1
public class ARequest : IRequest, IPipeline1 { }
public class BRequest : IRequest, IPipeline1 { }
public class CRequest : IRequest, IPipeline1 { }

// requests to be processed by pipeline 2
public class XRequest : IRequest, IPipeline2 { }
public class YRequest : IRequest, IPipeline2 { }
public class ZRequest : IRequest, IPipeline2 { }

Upvotes: 7

V&#225;clav Holuša
V&#225;clav Holuša

Reputation: 311

Not exactly response to your question, bit if you find yourself confused with the behavior registrations as their number grows, you can consider specifying them using the library I created for that purpose https://github.com/ITIXO/MediatR.Extensions.AttributedBehaviors

Upvotes: 2

MestreDosMagros
MestreDosMagros

Reputation: 1030

I don't think its a bad idea at all, you can create an interface for mark all the requests you want to implement the PipelineX, and other for PipelineY.

Ex:
You have the RequestOne and RequestTwo classes that need to go through PipelineX, so you create and interface like IPipelineOne and mark the classes with it, then use reflection to process inside the pripeline middleware. The PipelineY will still run through these two classes and the rest of the program as well with no problems

Upvotes: 4

Related Questions