MediatR 이 유료화를 앞두고 있어서, 패키지를 제거하고 있습니다.
이벤트, 파이프 파인 등의 기능 중에서 IRequest 의 구현 부분을 함수형으로 변경한 방법을 소개합니다.
기본 형식
namespace UseCases;
public interface IRequest;
public interface IRequest<TResponse>;
public delegate Task RequestHandler<TRequest>(TRequest request, CancellationToken token)
where TRequest : IRequest;
public delegate Task<TResponse> RequestHandler<TRequest, TResponse>(TRequest request, CancellationToken token)
where TRequest : IRequest<TResponse>;
Requests
using UseCases.Students;
namespace UseCases.Students;
public record QueryStudentByName(string StudentName)
: IRequest<StudentDto[]>
public record StudentDto(string Name);
프론트 엔드
HttpClient 핸들러
namespace Usecases.ClientHandlers;
static class StudentCaseHandlers
{
static readonly string _path = "/students";
public RequestHandler<QuerySturentByName, StudentDto[]> QueryStudentByNameHandler(this HttpClient proxy) =>
async (request, ct) =>
{
var path = $"{_path}?name={request.StudentName}";
var response = await proxy.GetAsync(path, ct);
return (await response.ReadFromJsonAsync<StudentDto[]>(ct)) ?? [];
}
소비 코드
using Usecases.ClientHandlers;
var ct = // ...
var request = // ...
var students = await _httpClient.QueryStudentByNameHandler().Invoke(request, ct);
백엔드
데이터 베이스 핸들러
namespace Usecases.DBHandlers;
public static class EFCoreHandlers
{
public RequestHandler<QueryStudentByName, StudentDto[]> QueryStudentByNameHandler(this DbContext db) =>
async (request, ct) =>
{
return await db.Set<Student>()
.Where(s => s.Name.Contains(request.StudentName))
.Select(ToDto)
.ToArrayAsync(ct);
}
소비 코드
using Usecases.DBHandlers;
app.MapGet("/students" async (string name, AppDbContext db, CancellationToken token) =>
{
var request = new QueryStudentByName(name);
return await db.QueryStudentByNameHandler().Invoke(request, token);
})
API 분리
Student 읽기 서비스.
using Usecases.DBHandlers;
app.MapGet("/students" async (string name, StudentQueryDbContext db, CancellationToken token) =>
{
var request = new QueryStudentByName(name);
return await db.QueryStudentByNameHandler().Invoke(request, token);
})