需要帮助让我的控制器在使用ASP.NET内核时变干
所以,基本上,我有一个问题,保持我的控制器脱脂和干燥。
基本上,假设我有4个控制器:controllerA、controllerB . controllerD --每个控制器的代码一般结构如下(伪代码)
class controllerA
{
IActionResult Get(string ids)
{
//do validation on ids - if invalid return 404
// IEnumerable<obj> results= aservice.GetResource(ids)
-------------------------------------------------------------------------
//Logging of results
//logic which looks at results and determines whether to return a 404 or a 200
//return results
}
} 虚线后的逻辑实质上是在4个控制器中重复的--如何使控制器更加干燥。
我读过不同的解决方案,包括使用DI服务、助手类、控制器类型的扩展方法或这些控制器可以继承的扩展.NET控制器类的抽象类。
我正在编写生产代码,所以想找一个干净的解决方案,这也是最好的实践!
谢谢!
发布于 2022-08-30 18:52:49
我建议使用MediatR nuget。您可以为每个所需的步骤实现IPipelineBehavior<,>,在您的示例中如下所示:
ids
的
您的代码如下所示:
public async Task<IActionResult> Get(CustomCommand request)
{
var result = await _mediator.Send(request);
// return handled result
}如果将命令定义为操作参数,它将更多地减少代码,如下所示
public async Task<IActionResult> Get(string ids)
{
// under the hood it will execute (depends on implementation):
// 1. validation of ids for the command
// 2. execute main logic which implemented in IRequestHandler<>
// 3. logging
// 4. return result
var result = await _mediator.Send(new CustomCommand(ids));
// return handled result
}关于结果处理,有两种常见的方法:函数式编程或使用异常。
使用异常
ValidationException)
NotFoundException、BadRequestException (在需要停止执行并返回不成功结果(例如,验证失败)的情况下,最好将其称为有意义的
函数式编程
而不是简单地返回响应,而是在响应中返回结果对象,这是Result<T>的简单实现。
public class Result<TValue>
{
public TValue Value { get; set; }
public bool IsSuccess { get; set; }
// you can add also something like 'ErrorCode' to specify how to handle
// failed result, for instance if ErrorCode is 400 (it can be readable
// string as well) you will return BadRequest()
}最后,您可以在基类控制器类中定义执行逻辑和处理结果的方法。
//... inside your base controller
public async Task<ActionResult<TResponse>> ExecuteAsync<TResponse>(IRequest<Result<TResponse>> request)
{
Result<TResponse> result = await Mediator.Send(request);
if(result.IsSuccess) return Ok(result.Value);
return result.ErrorCode switch
{
"some_error_code" => Conflict(result.ErrorMessage),
"other_code" => NotFound(),
_ => BadRequest(result.ErrorMessage)
};
}
//...因此行动代码将是:
public Task<IActionResult> Get(CustomCommand request) => ExecuteAsync(request); https://stackoverflow.com/questions/73493142
复制相似问题