ASP.NET Core Web API - 如何在 MediatR 中指定请求和响应 DTO

ASP.NET Core Web API - How to specify request and response DTOs in MediatR

在我的 ASP.NET Core-6 Web API 项目中,我正在使用 Fluent Validation 和 MediatR。

我已经有了这个代码:

型号:

public class Employee
{
    public int Id { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmployeeCode { get; set; }

    public int DepartmentId { get; set; }
    public Department Department { get; set; }
}

public class Department
{
    public Department()
    {
        Employees = new List<Employee>();
    }

    public int Id { get; set; }

    public string Name { get; set; }

    public IList<Employee> Employees { get; set; }

}

DTO:

public class DepartmentDto : IRegister
{
    public DepartmentDto()
    {
        Employees = new List<EmployeeDto>();
    }
    public int Id { get; set; }

    public string Name { get; set; }

    public IList<EmployeeDto> Employees { get; set; }

    public void Register(TypeAdapterConfig config)
    {
        config.NewConfig<Department, DepartmentDto>();
    }
}


public class DepartmentRequestDto : IRegister
{
    public string Name { get; set; }

    public void Register(TypeAdapterConfig config)
    {
        config.NewConfig<Department, DepartmentRequestDto>();
    }
}

public class DepartmentResponseDto : IRegister
{
    public DepartmentResponseDto()
    {
        Employees = new List<EmployeeDto>();
    }

    public string Name { get; set; }

    public IList<EmployeeDto> Employees { get; set; }

    public void Register(TypeAdapterConfig config)
    {
        config.NewConfig<Department, DepartmentResponseDto>();
    }
}

到目前为止,我有创建新部门的代码:

创建部门命令验证器:

public class CreateDepartmentCommandValidator : AbstractValidator<CreateDepartmentCommand>
{
    public CreateDepartmentCommandValidator()
    {
        RuleFor(v => v.Name)
            .MaximumLength(100).WithMessage("Name must not exceed 100 characters.")
            .NotEmpty().WithMessage("Name is required.");
    }
}

创建部门命令:

public class CreateDepartmentCommand : IRequestWrapper<DepartmentDto>
{
    public string Name { get; set; }
}

public class CreateDistrictCommandHandler : IRequestHandlerWrapper<CreateDistrictCommand, DistrictDto>
{
    private readonly IApplicationDbContext _context;
    private readonly IMapper _mapper;

    public CreateDistrictCommandHandler(IApplicationDbContext context, IMapper mapper)
    {
        _context = context;
        _mapper = mapper;
    }

    public async Task<ServiceResult<DepartmentDto>> Handle(CreateDepartmentCommand request, CancellationToken cancellationToken)
    {
        var entity = new District
        {
            Name = request.Name,
        };

        await _context.Departments.AddAsync(entity, cancellationToken);

        await _context.SaveChangesAsync(cancellationToken);

        return ServiceResult.Success(_mapper.Map<DepartmentDto>(entity));
    }
}

我不想使用上面的 CreateCommand 代码,而是希望将 DepartmentRequestDto 作为输入来替换部门模型。并且还希望它 return DepartmentResponseDto 作为输出(或响应)而不是那里的 DepartmentDto

我该如何实现?

谢谢

请求包装器:

public interface IRequestWrapper<T> : IRequest<ServiceResult<T>>
{
}

请求处理程序包装器:

public interface IRequestHandlerWrapper<in TRequest, TResponse> : IRequestHandler<TRequest, ServiceResult<TResponse>>
    where TRequest : IRequestWrapper<TResponse>
{
}

必须实现请求包装器的请求:

public class DepartmentRequestDto : IRequestWrapper<DepartmentResponseDto>
{
    public string Name { get; set; }
}

以及实现请求处理程序包装器的处理程序:

public class CreateDepartmentCommandHandler : IRequestHandlerWrapper<DepartmentRequestDto, DepartmentResponseDto>
{
    private readonly IApplicationDbContext _context;
    private readonly IMapper _mapper;

    public CreateDistrictCommandHandler(IApplicationDbContext context, IMapper mapper)
    {
        _context = context;
        _mapper = mapper;
    }

    public async Task<ServiceResult<DepartmentResponseDto>> Handle(DepartmentRequestDto request, CancellationToken cancellationToken)
    {
        var entity = new District
        {
            Name = request.Name,
        };

        _context.Departments.Add(entity);

        await _context.SaveChangesAsync(cancellationToken);

        return ServiceResult.Success(_mapper.Map<DepartmentResponseDto>(entity));
    }
}

响应结构随心所欲,没有任何要求:

public class DepartmentResponseDto
{
    // TODO: Add response model properties.
}