Skip to content

Instantly share code, notes, and snippets.

@distantcam
Last active January 9, 2023 08:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save distantcam/c1cd49b34f1abd73bf5ed7a46acd3238 to your computer and use it in GitHub Desktop.
Save distantcam/c1cd49b34f1abd73bf5ed7a46acd3238 to your computer and use it in GitHub Desktop.
C# 11 Static Endpoint Mapping
public interface IEndpointDefinition
{
static abstract void MapEndpoint(IEndpointRouteBuilder builder);
}
public static class EndpointRouteBuilderExtensions
{
private static readonly MethodInfo MapEndpointMethod = typeof(EndpointRouteBuilderExtensions).GetMethod(nameof(MapEndpoint), BindingFlags.NonPublic | BindingFlags.Static)!;
private static void MapEndpoint<T>(IEndpointRouteBuilder builder) where T : IEndpointDefinition => T.MapEndpoint(builder);
public static void MapEndpointDefinitionsFromAssemblyContaining<T>(this IEndpointRouteBuilder e) => MapEndpointDefinitiionsFromAssembly(e, typeof(T).Assembly);
public static void MapEndpointDefinitiionsFromAssembly(this IEndpointRouteBuilder builder, Assembly assembly)
{
ArgumentNullException.ThrowIfNull(builder);
ArgumentNullException.ThrowIfNull(assembly);
var endpointDefinitions = assembly.GetTypes().Where(t => typeof(IEndpointDefinition).IsAssignableFrom(t) && !t.IsInterface);
foreach (var endpointDefinition in endpointDefinitions)
{
MapEndpointMethod.MakeGenericMethod(endpointDefinition).Invoke(null, new[] { builder });
}
}
}
public class Ping : IRequest<string> { }
public class PingHandler : IRequestHandler<Ping, string>, IEndpointDefinition
{
public static void MapEndpoint(IEndpointRouteBuilder builder) => builder
.MapGet("/ping", ([FromServices] IMediator mediator, [AsParameters] Ping ping) => mediator.Send(ping));
public Task<string> Handle(Ping request, CancellationToken cancellationToken)
{
return Task.FromResult("Pong");
}
}
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMediatR(Assembly.GetExecutingAssembly());
builder.Services.AddScoped<PingHandler>();
var app = builder.Build();
app.MapEndpointDefinitionsFromAssemblyContaining<Program>();
app.Run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment