jbogard / MediatR

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

Is there support for response types as tuples? #1052

Closed digitalpacman closed 1 month ago

digitalpacman commented 4 months ago

I am looking to have the request return a tuple of (T, Common). However when implemented as a behavior, it appears to not match and execute. Looking around it looks like IPipelineBehavior only works when the generics are fixed as <T, T2> for the generics. I see everywhere that instead of IResult you want to use it as a constraint. However you can't use constraints for tuples like this.

I do not want to have to add this extra property to all my responses. But it looks like I'll have to build my own mediator pattern implementation, or switch to updating all my responses.

I would expect the bottom to output "Bar" but it outputs "Foo".


async Task Main()
{
    var services = new ServiceCollection();
    services.AddMediatR(cfg =>
    {
        cfg.RegisterServicesFromAssembly(this.GetType().Assembly);
        cfg.AddOpenBehavior(typeof(FooBehavior<,>));
    });
    var provider = services.BuildServiceProvider();
    var (response, common) = await provider.GetRequiredService<IMediator>().Send(new FooArgs());
    Console.WriteLine(response);
    Console.WriteLine(common);
}

public class FooBehavior<TRequest, TResponse>() : IPipelineBehavior<TRequest, (TResponse, BarCommon?)>
    where TResponse : class
{
    public Task<(TResponse, BarCommon?)> Handle(TRequest request, RequestHandlerDelegate<(TResponse, BarCommon?)> next, CancellationToken cancellationToken)
    {
        return Task.FromResult<(TResponse, BarCommon?)>(((TResponse)null, BarCommon.Bar));
    }
}

public class FooArgs : IRequest<(BarResponse, BarCommon?)>
{
}

public class FooHandler() : IRequestHandler<FooArgs, (BarResponse, BarCommon?)>
{
    public Task<(BarResponse, BarCommon?)> Handle(FooArgs request, CancellationToken cancellationToken)
    {
        return Task.FromResult<(BarResponse, BarCommon?)>(((BarResponse) null, BarCommon.Foo));
    }
}

public enum BarCommon
{
    Bar,
    Foo,
}
zachpainter77 commented 4 months ago

I'm pretty sure tuples as response types are fine.

I just tried this and it worked like a charm.

 public class TupleRequest : IRequest<(int TheInt, string TheString)>
 {
     public int TheInt { get; set; }
     public string? TheString { get; set; }
 }

 public class TupleRequestHandler : IRequestHandler<TupleRequest, (int, string)>
 {
     public Task<(int, string)> Handle(TupleRequest request, CancellationToken cancellationToken)
     {
         return Task.FromResult(( request.TheInt, request.TheString! ));
     }
 }
digitalpacman commented 4 months ago

The request handler worked but not the custom behavior

On Wed, Jul 24, 2024, 10:05 AM Zach Painter @.***> wrote:

I'm pretty sure tuples as response types are fine.

I just tried this and it worked like a charm.

public class TupleRequest : IRequest<(int TheInt, string TheString)> { public int TheInt { get; set; } public string? TheString { get; set; } }

public class TupleRequestHandler : IRequestHandler<TupleRequest, (int, string)> { public Task<(int, string)> Handle(TupleRequest request, CancellationToken cancellationToken) { return Task.FromResult(( request.TheInt, request.TheString! )); } }

— Reply to this email directly, view it on GitHub https://github.com/jbogard/MediatR/issues/1052#issuecomment-2248253212, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFMKV4XGSWS4BWBMACQ7ATZN67D3AVCNFSM6AAAAABLL3FZQWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENBYGI2TGMRRGI . You are receiving this because you authored the thread.Message ID: @.***>

github-actions[bot] commented 2 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.

github-actions[bot] commented 1 month ago

This issue was closed because it has been stalled for 14 days with no activity.