Here are some suggestions from .net 7. Please take this as they are, suggestions, I'm not saying it's better or worse just some alternatives. Congratulations for this awesome sample!
Lately we've been merging the the request, validator, handler in the same class. Since adding or removing the request will almost always involve changing the validator. F12 (Go to definition is magical). We do not use any auto discovery plain old container registration so navigation and find usages work.
public static class Endpoint
{
public static void MapRoute(IEndpointRouteBuilder route) => route.MapGet("/account/{id:int}", Handle);
public record Request
{
public required int Id { get; init; }
}
public class Validator : AbstractValidator<Request>
{
public Validator() => RuleFor(x => x.Id).GreaterThan(2);
}
public record Response(string Desc);
public static async Task<Results<Ok<Response>, NotFound>> Handle(
[AsParameters] Request request,
ILogger<Request> logger,
ApiDbContext context,
CancellationToken cancellationToken)
{
if (request.Id == 10)
{
return NotFound();
}
var entity = await context.Students.FirstOrDefaultAsync(cancellationToken: cancellationToken);
return Ok(new Response($"everything went fine for: {request.Id}"));
}
}
In case you want to do unit tests instead of acceptance tests of your endpoints you can inject Queries and Commands instead of db context so you can easily mock.
We've tried TestContainers with server instance per session and each tests gets a new database + migration. It takes 10 sec to start sql server (azure sql edge) and 4ms to create a random new db with 2 tables. Running an acceptance test which: 1. generates new db. 2. creates the tables. 3. starts the api with test server. 4. makes a http get 5. make a query in db. 5. returns response. Takes 1 sec on average. This way ALL tests are insolated and run in parallel (even in the same (implicit) collection).
I'm planning a PoC for TestContainers with RabbitMq where only one instance of rabbitmq is started for a test session (per assembly fixutre) and all tests will use a separate vhost.
We've also dropped MediatR since we have very few truly cross concerns for it's pipeline and the number of request.