• 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 交流 ~ 
    
  • 相关阅读:
    Linux的目录结构
    【C++】C++基础知识(七)---指针
    【C语言】贪吃蛇【附源码】
    高防服务器中的秒解服务器什么意思?
    idea2023帅气的jpa函数生成辅助工具
    Spring底层原理学习笔记--第三讲--(bean生命周期与模板方法)
    Presto资源管理之Resource Groups And Selector
    NewStarCTF 2023 week5--web
    数据结构与算法面试
    我的世界Minecraft Java开服教程(Windows)开服器开服包下载开服网站服务器开服核心开服端开服软件mac版Java启动器资源包
  • 原文地址:https://www.cnblogs.com/vipwan/p/biwen-quickapi-gen.html