Closed irpg7 closed 6 months ago
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days.
Up @jbogard
Hello, you should be able to just remove the type constraint completely. e.g. see WithEitherPipelineBehaviour
below, if it matters for some reason you could also replace the type constraint with where TRequest : IBaseRequest
using MediatR;
using MediatR.Pipeline;
using Microsoft.Extensions.DependencyInjection;
using mytest;
// Create a new service collection and add mediatr
var services = new ServiceCollection();
services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(Program).Assembly));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(NoReturnPipelineBehaviour<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(WithReturnPipelineBehaviour<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(WithEitherPipelineBehaviour<,>));
// Build the service provider
var serviceProvider = services.BuildServiceProvider();
using var scope = serviceProvider.CreateScope();
var mediatr = scope.ServiceProvider.GetRequiredService<IMediator>();
await mediatr.Send(new RequestNoReturn());
await mediatr.Send(new RequestWithReturn());
internal record RequestNoReturn : IRequest
{
}
internal record RequestWithReturn : IRequest<int>
{
}
internal class RequestNoReturnHandler : IRequestHandler<RequestNoReturn>
{
public Task Handle(RequestNoReturn notification, CancellationToken cancellationToken)
{
Console.WriteLine("WithoutReturn");
return Task.CompletedTask;
}
}
internal class RequestWithReturnHandler : IRequestHandler<RequestWithReturn, int>
{
public Task<int> Handle(RequestWithReturn request, CancellationToken cancellationToken)
{
Console.WriteLine("WithReturn");
return Task.FromResult(2);
}
}
internal class NoReturnPipelineBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest
{
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
Console.WriteLine($"{this.GetType()} Before");
var response = await next();
Console.WriteLine($"{this.GetType()} After");
return response;
}
}
internal class WithReturnPipelineBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<TResponse>
{
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
Console.WriteLine($"{this.GetType()} Before");
var response = await next();
Console.WriteLine($"{this.GetType()} After");
return response;
}
}
internal class WithEitherPipelineBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
Console.WriteLine($"{this.GetType()} Before");
var response = await next();
Console.WriteLine($"{this.GetType()} After");
return response;
}
}
This code returns
NoReturnPipelineBehaviour`2[RequestNoReturn,MediatR.Unit] Before
WithEitherPipelineBehaviour`2[RequestNoReturn,MediatR.Unit] Before
WithoutReturn
WithEitherPipelineBehaviour`2[RequestNoReturn,MediatR.Unit] After
NoReturnPipelineBehaviour`2[RequestNoReturn,MediatR.Unit] After
WithReturnPipelineBehaviour`2[RequestWithReturn,System.Int32] Before
WithEitherPipelineBehaviour`2[RequestWithReturn,System.Int32] Before
WithReturn
WithEitherPipelineBehaviour`2[RequestWithReturn,System.Int32] After
WithReturnPipelineBehaviour`2[RequestWithReturn,System.Int32] After
I don't think that's a clean approach to make/register 2 of same purpose pipelines, however i already know i can make it a single interface. What i tried to say is it's confusing since both are IRequest.
Your pipeline behavior doesn't need that constraint. It's been changed to just notnull
:
https://github.com/jbogard/MediatR/blob/master/src/MediatR/IPipelineBehavior.cs#L20
See also the upgrade guides about this change. That should fix everything for you.
Hello,
when i apply this constraint on my validation behavior. Its just skips the pipeline process, when i don't need a response from command. but i actually need to apply some validation rules. also when i remove the TResponse, it works only for IRequest ones.
doing these kinda commands, always skips the validation part, which is valid because it doesn't have a response parameter. But i think i should be able to validate even if i don't have response on my "out" part. i believe that creates some confusion. can you sort it out ? Thanks