Skip to content

Commit

Permalink
⚗️ Improve EndpointGroupBase to support method based handlers.
Browse files Browse the repository at this point in the history
  • Loading branch information
jasontaylordev committed Jul 1, 2023
1 parent 83e31a7 commit 3846c6e
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 26 deletions.
55 changes: 30 additions & 25 deletions src/WebUI/Endpoints/TodoListsEndpointGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,46 @@
using CleanArchitecture.Application.TodoLists.Commands.UpdateTodoList;
using CleanArchitecture.Application.TodoLists.Queries.ExportTodos;
using CleanArchitecture.Application.TodoLists.Queries.GetTodos;

namespace CleanArchitecture.WebUI.Endpoints;

public class TodoListsEndpointGroup : EndpointGroupBase
{
public override void Map(WebApplication app)
{
MapGroup("TodoLists", app);
MapGroup(app, "TodoLists");
MapGet(GetTodoLists);
MapGet(ExportTodos, "Export/{id}");
MapPost(CreateTodoList);
MapPut(UpdateTodoList, "{id}");
MapDelete(DeleteTodoList, "{id}");
}

MapGet("GetTodoLists",
async (ISender sender) => await sender.Send(new GetTodosQuery()));
public async Task<TodosVm> GetTodoLists(ISender sender)
{
return await sender.Send(new GetTodosQuery());
}

MapGet("ExportTodos", "Export/{id}",
async (ISender sender, int id) =>
{
var vm = await sender.Send(new ExportTodosQuery { ListId = id });
return Results.File(vm.Content, vm.ContentType, vm.FileName);
});
public async Task<IResult> ExportTodos(ISender sender, int id)
{
var vm = await sender.Send(new ExportTodosQuery { ListId = id });
return Results.File(vm.Content, vm.ContentType, vm.FileName);
}

MapPost("CreateTodoList",
async (ISender sender, CreateTodoListCommand command) => await sender.Send(command));
public async Task<int> CreateTodoList(ISender sender, CreateTodoListCommand command)
{
return await sender.Send(command);
}

MapPut("UpdateTodoList", "{id}",
async (ISender sender, int id, UpdateTodoListCommand command) =>
{
if (id != command.Id) return Results.BadRequest();
await sender.Send(command);
return Results.NoContent();
});
public async Task<IResult> UpdateTodoList(ISender sender, int id, UpdateTodoListCommand command)
{
if (id != command.Id) return Results.BadRequest();
await sender.Send(command);
return Results.NoContent();
}

MapDelete("DeleteTodoList", "{id}",
async (ISender sender, int id) =>
{
await sender.Send(new DeleteTodoListCommand(id));
return Results.NoContent();
});
public async Task<IResult> DeleteTodoList(ISender sender, int id)
{
await sender.Send(new DeleteTodoListCommand(id));
return Results.NoContent();
}
}
42 changes: 41 additions & 1 deletion src/WebUI/Infrastructure/EndpointGroupBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public abstract class EndpointGroupBase

public abstract void Map(WebApplication app);

protected void MapGroup(string groupName, WebApplication app)
protected void MapGroup(WebApplication app, string groupName)
{
_groupName = groupName;

Expand All @@ -22,6 +22,16 @@ protected void MapGroup(string groupName, WebApplication app)
.AddEndpointFilter<ApiExceptionFilter>();
}

public void MapGet(Delegate handler, string prefix = "")
{
if (handler.Method.IsAnonymous())
{
throw new ArgumentException("The endpoint name must be specified when using anonymous handlers.");
}

MapGet(handler.Method.Name, prefix, handler);
}

protected void MapGet(string name, Delegate handler)
{
MapGet(name, "", handler);
Expand All @@ -33,6 +43,16 @@ protected void MapGet(string name, string prefix, Delegate handler)
.WithName(GetEndpointName(name));
}

public void MapPost(Delegate handler, string prefix = "")
{
if (handler.Method.IsAnonymous())
{
throw new ArgumentException("The endpoint name must be specified when using anonymous handlers.");
}

MapPost(handler.Method.Name, prefix, handler);
}

protected void MapPost(string name, Delegate handler)
{
MapPost(name, "", handler);
Expand All @@ -44,12 +64,32 @@ protected void MapPost(string name, string prefix, Delegate handler)
.WithName(GetEndpointName(name));
}

protected void MapPut(Delegate handler, string prefix)
{
if (handler.Method.IsAnonymous())
{
throw new ArgumentException("The endpoint name must be specified when using anonymous handlers.");
}

MapPut(handler.Method.Name, prefix, handler);
}

protected void MapPut(string name, string prefix, Delegate handler)
{
_group!.MapPut(prefix, handler)
.WithName(GetEndpointName(name));
}

protected void MapDelete(Delegate handler, string prefix)
{
if (handler.Method.IsAnonymous())
{
throw new ArgumentException("The endpoint name must be specified when using anonymous handlers.");
}

MapDelete(handler.Method.Name, prefix, handler);
}

protected void MapDelete(string name, string prefix, Delegate handler)
{
_group!.MapDelete(prefix, handler)
Expand Down
12 changes: 12 additions & 0 deletions src/WebUI/Infrastructure/MethodInfoExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Reflection;

namespace CleanArchitecture.WebUI.Infrastructure;

public static class MethodInfoExtensions
{
public static bool IsAnonymous(this MethodInfo method)
{
var invalidChars = new[] { '<', '>' };
return method.Name.Any(invalidChars.Contains);
}
}

0 comments on commit 3846c6e

Please sign in to comment.