• Biwen.QuickApi代码生成器功能上线


    
    [QuickApi("hello/world")]
    public class MyApi : BaseQuickApi{}
    
    

    使用方式 :

     dotnet add package Biwen.QuickApi
     dotnet add package Biwen.QuickApi.SourceGenerator
    

    最后简简单单注册路由:

    app.MapGenQuickApis("api");
    

    Biwen.QuickApi 使用REPR风格写的minimalApi已经写完了, 最近看到道友们都玩SourceGen提升代码性能
    ,所以一鼓作气 自己也实现了一个 Biwen.QuickApi的 代码生成器版本 用以替换 代码中反射和dynamic带来的性能问题

    Biwen.QuickApi下面这一段核心代码:

                var req = await ((dynamic)api).ReqBinder.BindAsync(ctx.HttpContext!);
                //验证DTO
               if (req.RealValidator.Validate(req) is ValidationResult vresult && !vresult!.IsValid)
                 {
                    return Results.ValidationProblem(vresult.ToDictionary());
                  }
                try
                {
                    //var result = await method.Invoke(api, new object[] { req! })!;
                    var result = await ((dynamic)api)!.ExecuteAsync(req!);
                    if (result is EmptyResponse)
                    {
                        return Results.Ok();
                    }
                    if (result is ContentResponse content)
                    {
                        return Results.Content(content.Content);
                    }
                    Func rspToExpandoObject = (rsp) =>
                    {
                        if (rsp == null) return null;
                        var type = rsp.GetType() as Type;
                        var hasAlias = type!.GetProperties().Any(x => x.GetCustomAttribute() != null);
                        if (!hasAlias)
                        {
                            return rsp;
                        }
                        dynamic expandoObject = new ExpandoObject();
                        foreach (var prop in type.GetProperties())
                        {
                            var alias = prop.GetCustomAttribute();
                            ((IDictionary<string, object>)expandoObject)[alias != null ? alias.Name : prop.Name] = prop.GetValue(rsp);
                        }
                        return expandoObject;
                    };
                    var expandoResult = rspToExpandoObject(result);
                    return Results.Json(expandoResult, quickApiOptions?.JsonSerializerOptions);
                }
                catch (Exception ex)
                {
                    var exceptionHandlers = ctx.HttpContext!.RequestServices.GetServices();
                    //异常处理
                    foreach (var handler in exceptionHandlers)
                    {
                        await handler.HandleAsync(ex);
                    }
                    //默认处理
                    throw;
                }
    

    Biwen.QuickApi的原理就是反射查找所有标记[QuickApi]特征的Api,然后批量注册服务&批量映射路由. 路由请求执行的方法体使用了上面那一段可能性能堪忧的代码. 如果用Gen的方式那么 上面一段代码就都变成了强类型引用 生成如下的结果 :

    
    //绑定对象
    var req = await api.ReqBinder.BindAsync(ctx.HttpContext!);
    //验证器
    if (req.RealValidator.Validate(req) is ValidationResult vresult && !vresult!.IsValid)
    {
    	return Results.ValidationProblem(vresult.ToDictionary());
    }
    //执行请求
    try
    {
    	var result = await api.ExecuteAsync(req!);
    	return Results.Json(result);
    }
    catch (Exception ex)
    {
    	var exceptionHandlers = ctx.HttpContext!.RequestServices.GetServices();
    	//异常处理
    	foreach (var handler in exceptionHandlers)
    	{
    		await handler.HandleAsync(ex);
    	}
    	//默认处理
    	throw;
    }
    ```这个就爽歪歪了 反射的问题没有了 动态类型也不见了 性能直接提升了 !
    
    最后 Gen的实现代码可以翻看.
    https://github.com/vipwan/Biwen.QuickApi 这里就不赘述了. 
    
    欢迎 star 交流 ~ 
    
  • 相关阅读:
    Qt绘制椭圆曲线的角度问题(离心角和旋转角)
    大数据Doris(十八):演示单分区和复合分区
    将Abp移植进.NET MAUI项目(一):搭建项目
    数据库(一)
    阿里在职5年,一个女测试工师的坎坷之路
    Docker 配置阿里云镜像加速器
    加班整理出来的MySQL数据库基本操作送给大家,非常详细...
    HTML5的新特性有哪些?
    多线程理论基础
    LastPass 开发者系统被黑客窃取源代码
  • 原文地址:https://www.cnblogs.com/vipwan/p/biwen-quickapi-gen.html