I am creating an dotnet core C# Web API app using wolverine (probably not important)
Each Command is configured in program like so by Mapping a Post.
public record CreateIssue(Guid OriginatorId, string Title, string Description);
public record AssignIssue(Guid IssueId, Guid AssigneeId);
...
app.MapPost("/issues/create", (CreateIssue body, IMessageBus bus) => bus.InvokeAsync(body));
app.MapPost("/issues/assign", (AssignIssue body, IMessageBus bus) => bus.InvokeAsync(body));
I wanted to make this configuration free and just have it work whenever I create a new command.
I get all of types of command
var commands = typeof(CreateIssue).GetTypeInfo().Assembly.GetExportedTypes()
.Where(t => t.Namespace == typeof(CreateIssue).GetTypeInfo().Namespace)
.Where(t => t.GetMethod("<Clone>$") is object); //isRecord
Then I loop on these types
foreach (Type command in commands)
{
app.MapPost($"/command/{command.Name}", (??? body, IMessageBus bus) => bus.InvokeAsync(body))
.Accepts(command, "application/json").Produces(StatusCodes.Status200OK);
}
My problem is I need to set the body to the command type (??? above) so that it can model bind. How can I accomplish this?
So I managed to get this working.
in Program I call a new extension method
app.MapWolverineCommands();Then the extension method looks like this:
This is good enough that I can also drop the calls to
.Accepts<TCommand>("application/json").Produces(StatusCodes.Status200OK);which I added to allow Swagger to know the generic types but this has become redundant.