Add contracts and endpoint filters
This commit is contained in:
parent
94d4e1352f
commit
cc5ed32cad
@ -6,4 +6,8 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<FrameworkReference Include="Microsoft.AspNetCore.App"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -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<TResponse>(object? value, [NotNullWhen(true)] out IRequest<TResponse>? request);
|
||||||
|
|
||||||
|
ValueTask SendAsync(IRequest request, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
ValueTask<TResponse> SendAsync<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken = default);
|
||||||
|
}
|
||||||
5
src/Baguette.Extensions.AspNetCore.Mediator/IRequest.cs
Normal file
5
src/Baguette.Extensions.AspNetCore.Mediator/IRequest.cs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
namespace Baguette.Extensions.AspNetCore.Mediator;
|
||||||
|
|
||||||
|
public interface IRequest<out TResponse>;
|
||||||
|
|
||||||
|
public interface IRequest;
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Baguette.Extensions.AspNetCore.Mediator;
|
||||||
|
|
||||||
|
public class SendEndpointRequestFilter<TResponse> : IEndpointFilter
|
||||||
|
{
|
||||||
|
public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
|
||||||
|
{
|
||||||
|
var mediator = context.HttpContext.RequestServices.GetRequiredService<IMediatorService>();
|
||||||
|
|
||||||
|
var value = await next(context);
|
||||||
|
|
||||||
|
if (value is IResult)
|
||||||
|
return value;
|
||||||
|
|
||||||
|
if (!mediator.TryGetRequest<TResponse>(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<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
|
||||||
|
{
|
||||||
|
var mediator = context.HttpContext.RequestServices.GetRequiredService<IMediatorService>();
|
||||||
|
|
||||||
|
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<TResponse>(this RouteHandlerBuilder builder)
|
||||||
|
{
|
||||||
|
return builder.AddEndpointFilter<SendEndpointRequestFilter<TResponse>>().Produces<TResponse>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RouteHandlerBuilder SendRequest(this RouteHandlerBuilder builder)
|
||||||
|
{
|
||||||
|
return builder.AddEndpointFilter<SendEndpointRequestFilter>().Produces(StatusCodes.Status200OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user