.NET Core开发实战(定义API的最佳实践)Source Generators版

前言

极客时间上的《.NET Core开发实战》是一门非常好的课程,作者肖伟宇在第31课(https://time.geekbang.org/course/detail/100044601-201165)介绍了定义API的最佳实践

大意如下:

Controller这一层负责与前端用户的交互,它主要的责任就是定义输入和输出,不应该处理业务。 

因此使用中介者模式,将业务逻辑和Controller进行隔离。

示例API的实现代码如下:

[Route("api/[controller]")]
[ApiController]
public class OrderController : ControllerBase
{
    IMediator _mediator;
    public OrderController(IMediator mediator)
    {
        _mediator = mediator;
    }

    [HttpPost]
    public async Task<long> CreateOrder([FromBody]CreateOrderCommand cmd)
    {
        return await _mediator.Send(cmd, HttpContext.RequestAborted);
    }

    [HttpGet]
    public async Task<List<string>> QueryOrder([FromQuery]MyOrderQuery myOrderQuery)
    {
        return await _mediator.Send(myOrderQuery);
    }
}

public class CreateOrderCommand : IRequest<long>
{
    public CreateOrderCommand(int itemCount)
    {
        ItemCount = itemCount;
    }

    public long ItemCount { get; private set; }
}

public class MyOrderQuery : IRequest<List<string>>
{
    public string UserName { get; set; }
}

问题

按照上述的最佳实践去编写Controller,这就意味着,如果有100个命令和查询,就要创建100个同样格式的方法。

这是一项重复并且枯燥的工作,而且还必须保证方法返回值与IRequest<T>的类型一致,很容易出错。

有不有不用写这些代码的简单方式

Source Generators

现在,可以祭出我们的大杀器——Source Generators

上次我们已经使用它实现了AutoMapper,它的主要特点是自动生成源代码并编译到最终输出中。

这次,我们用它来自动生成API代码。

实现原理如下:

  • 遍历所有继承IRequest<T>的类,并用它们名称的第2个单词(例如Order)分组

  • 分组Key作为Controller的名称

  • 在Controller分组中遍历分组下的类,生成对应命令和查询方法

具体实现代码请到https://github.com/feiyun0112/CodesForMy_IO下载。

使用示例

下载课件代码(https://gitee.com/geektime-geekbang/NET-Core),在GeekTime.Ordering.API项目中引用ApiControllerGenerator项目,无需修改任何代码,直接编译,可以看到已经按照最佳实践的规范生成了代码(Controller名称故意加了New以示区别):

运行后Swagger显示正常,成功!

结论

现在,我们只需定义命令和查询,即可实现定义API的最佳实践,是不是很酷!

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值