翼度科技»论坛 编程开发 .net 查看内容

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

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
  1. [QuickApi("hello/world")]
  2. public class MyApi : BaseQuickApi<Req,Rsp>{}
复制代码
使用方式 :
  1. dotnet add package Biwen.QuickApi
  2. dotnet add package Biwen.QuickApi.SourceGenerator
复制代码
最后简简单单注册路由:
  1. app.MapGenQuickApis("api");
复制代码
Biwen.QuickApi 使用REPR风格写的minimalApi已经写完了, 最近看到道友们都玩SourceGen提升代码性能
,所以一鼓作气 自己也实现了一个 Biwen.QuickApi的 代码生成器版本 用以替换 代码中反射和dynamic带来的性能问题
Biwen.QuickApi下面这一段核心代码:
  1.             var req = await ((dynamic)api).ReqBinder.BindAsync(ctx.HttpContext!);
  2.             //验证DTO
  3.            if (req.RealValidator.Validate(req) is ValidationResult vresult && !vresult!.IsValid)
  4.              {
  5.                 return Results.ValidationProblem(vresult.ToDictionary());
  6.               }
  7.             try
  8.             {
  9.                 //var result = await method.Invoke(api, new object[] { req! })!;
  10.                 var result = await ((dynamic)api)!.ExecuteAsync(req!);
  11.                 if (result is EmptyResponse)
  12.                 {
  13.                     return Results.Ok();
  14.                 }
  15.                 if (result is ContentResponse content)
  16.                 {
  17.                     return Results.Content(content.Content);
  18.                 }
  19.                 Func<dynamic?, dynamic?> rspToExpandoObject = (rsp) =>
  20.                 {
  21.                     if (rsp == null) return null;
  22.                     var type = rsp.GetType() as Type;
  23.                     var hasAlias = type!.GetProperties().Any(x => x.GetCustomAttribute<AliasAsAttribute>() != null);
  24.                     if (!hasAlias)
  25.                     {
  26.                         return rsp;
  27.                     }
  28.                     dynamic expandoObject = new ExpandoObject();
  29.                     foreach (var prop in type.GetProperties())
  30.                     {
  31.                         var alias = prop.GetCustomAttribute<AliasAsAttribute>();
  32.                         ((IDictionary<string, object>)expandoObject)[alias != null ? alias.Name : prop.Name] = prop.GetValue(rsp);
  33.                     }
  34.                     return expandoObject;
  35.                 };
  36.                 var expandoResult = rspToExpandoObject(result);
  37.                 return Results.Json(expandoResult, quickApiOptions?.JsonSerializerOptions);
  38.             }
  39.             catch (Exception ex)
  40.             {
  41.                 var exceptionHandlers = ctx.HttpContext!.RequestServices.GetServices<IQuickApiExceptionHandler>();
  42.                 //异常处理
  43.                 foreach (var handler in exceptionHandlers)
  44.                 {
  45.                     await handler.HandleAsync(ex);
  46.                 }
  47.                 //默认处理
  48.                 throw;
  49.             }
复制代码
Biwen.QuickApi的原理就是反射查找所有标记[QuickApi]特征的Api,然后批量注册服务&批量映射路由. 路由请求执行的方法体使用了上面那一段可能性能堪忧的代码. 如果用Gen的方式那么 上面一段代码就都变成了强类型引用 生成如下的结果 :
  1. //绑定对象
  2. var req = await api.ReqBinder.BindAsync(ctx.HttpContext!);
  3. //验证器
  4. if (req.RealValidator.Validate(req) is ValidationResult vresult && !vresult!.IsValid)
  5. {
  6.         return Results.ValidationProblem(vresult.ToDictionary());
  7. }
  8. //执行请求
  9. try
  10. {
  11.         var result = await api.ExecuteAsync(req!);
  12.         return Results.Json(result);
  13. }
  14. catch (Exception ex)
  15. {
  16.         var exceptionHandlers = ctx.HttpContext!.RequestServices.GetServices<IQuickApiExceptionHandler>();
  17.         //异常处理
  18.         foreach (var handler in exceptionHandlers)
  19.         {
  20.                 await handler.HandleAsync(ex);
  21.         }
  22.         //默认处理
  23.         throw;
  24. }
  25. ```这个就爽歪歪了 反射的问题没有了 动态类型也不见了 性能直接提升了 !
  26. 最后 Gen的实现代码可以翻看.
  27. https://github.com/vipwan/Biwen.QuickApi 这里就不赘述了.
  28. 欢迎 star 交流 ~
复制代码
来源:https://www.cnblogs.com/vipwan/archive/2023/09/27/biwen-quickapi-gen.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具