diff --git a/src/Baguette.Extensions.AspNetCore.Mediator/Baguette.Extensions.AspNetCore.Mediator.csproj b/src/Baguette.Extensions.AspNetCore.Mediator/Baguette.Extensions.AspNetCore.Mediator.csproj index 3a63532..80ede92 100644 --- a/src/Baguette.Extensions.AspNetCore.Mediator/Baguette.Extensions.AspNetCore.Mediator.csproj +++ b/src/Baguette.Extensions.AspNetCore.Mediator/Baguette.Extensions.AspNetCore.Mediator.csproj @@ -6,4 +6,8 @@ enable + + + + diff --git a/src/Baguette.Extensions.AspNetCore.Mediator/IMediatorService.cs b/src/Baguette.Extensions.AspNetCore.Mediator/IMediatorService.cs new file mode 100644 index 0000000..8373de3 --- /dev/null +++ b/src/Baguette.Extensions.AspNetCore.Mediator/IMediatorService.cs @@ -0,0 +1,14 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Baguette.Extensions.AspNetCore.Mediator; + +public interface IMediatorService +{ + bool TryGetRequest(object? value, [NotNullWhen(true)] out IRequest? request); + + bool TryGetRequest(object? value, [NotNullWhen(true)] out IRequest? request); + + ValueTask SendAsync(IRequest request, CancellationToken cancellationToken = default); + + ValueTask SendAsync(IRequest request, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/Baguette.Extensions.AspNetCore.Mediator/IRequest.cs b/src/Baguette.Extensions.AspNetCore.Mediator/IRequest.cs new file mode 100644 index 0000000..97113cd --- /dev/null +++ b/src/Baguette.Extensions.AspNetCore.Mediator/IRequest.cs @@ -0,0 +1,5 @@ +namespace Baguette.Extensions.AspNetCore.Mediator; + +public interface IRequest; + +public interface IRequest; \ No newline at end of file diff --git a/src/Baguette.Extensions.AspNetCore.Mediator/SendEndpointRequestFilter.cs b/src/Baguette.Extensions.AspNetCore.Mediator/SendEndpointRequestFilter.cs new file mode 100644 index 0000000..9b83beb --- /dev/null +++ b/src/Baguette.Extensions.AspNetCore.Mediator/SendEndpointRequestFilter.cs @@ -0,0 +1,58 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; + +namespace Baguette.Extensions.AspNetCore.Mediator; + +public class SendEndpointRequestFilter : IEndpointFilter +{ + public async ValueTask InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next) + { + var mediator = context.HttpContext.RequestServices.GetRequiredService(); + + var value = await next(context); + + if (value is IResult) + return value; + + if (!mediator.TryGetRequest(value, out var typedRequest)) + throw new InvalidOperationException(); // TODO: Handle case where the request is not an IRequest + + var response = await mediator.SendAsync(typedRequest, context.HttpContext.RequestAborted); + + return response; + } +} + +public class SendEndpointRequestFilter : IEndpointFilter +{ + public async ValueTask InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next) + { + var mediator = context.HttpContext.RequestServices.GetRequiredService(); + + var value = await next(context); + + if (value is IResult) + return value; + + if (!mediator.TryGetRequest(value, out var typedRequest)) + throw new InvalidOperationException(); // TODO: Handle case where the request is not an IRequest + + await mediator.SendAsync(typedRequest, context.HttpContext.RequestAborted); + + return null; + } +} + +public static class MediatorEndpointRouteBuilderExtensions +{ + public static RouteHandlerBuilder SendRequest(this RouteHandlerBuilder builder) + { + return builder.AddEndpointFilter>().Produces(); + } + + public static RouteHandlerBuilder SendRequest(this RouteHandlerBuilder builder) + { + return builder.AddEndpointFilter().Produces(StatusCodes.Status200OK); + } +} \ No newline at end of file