首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >需要帮助使dotnet控制器干燥

需要帮助使dotnet控制器干燥
EN

Stack Overflow用户
提问于 2022-08-25 20:02:46
回答 1查看 157关注 0票数 2

需要帮助让我的控制器在使用ASP.NET内核时变干

所以,基本上,我有一个问题,保持我的控制器脱脂和干燥。

基本上,假设我有4个控制器:controllerAcontrollerB . controllerD --每个控制器的代码一般结构如下(伪代码)

代码语言:javascript
复制
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控制器类的抽象类。

我正在编写生产代码,所以想找一个干净的解决方案,这也是最好的实践!

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2022-08-30 18:52:49

我建议使用MediatR nuget。您可以为每个所需的步骤实现IPipelineBehavior<,>,在您的示例中如下所示:

ids

  • Logging

  • 验证

您的代码如下所示:

代码语言:javascript
复制
public async Task<IActionResult> Get(CustomCommand request)
{
   var result = await _mediator.Send(request);
   // return handled result
}

如果将命令定义为操作参数,它将更多地减少代码,如下所示

代码语言:javascript
复制
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)

  • Throw

  • 为您的服务创建客户异常,例如NotFoundExceptionBadRequestException (在需要停止执行并返回不成功结果(例如,验证失败)的情况下,最好将其称为有意义的

  • )

  • 将全局异常筛选器添加到asp.net,这将取决于它的类型,并可能使用来自asp.net的自定义数据

函数式编程

而不是简单地返回响应,而是在响应中返回结果对象,这是Result<T>的简单实现。

代码语言:javascript
复制
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()

}

最后,您可以在基类控制器类中定义执行逻辑和处理结果的方法。

代码语言:javascript
复制
//... 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)
   };
}
//...

因此行动代码将是:

代码语言:javascript
复制
public Task<IActionResult> Get(CustomCommand request) => ExecuteAsync(request); 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73493142

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档