|
- [QuickApi("hello/world")]
- public class MyApi : BaseQuickApi<Req,Rsp>{}
复制代码 使用方式 :- 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<dynamic?, dynamic?> rspToExpandoObject = (rsp) =>
- {
- if (rsp == null) return null;
- var type = rsp.GetType() as Type;
- var hasAlias = type!.GetProperties().Any(x => x.GetCustomAttribute<AliasAsAttribute>() != null);
- if (!hasAlias)
- {
- return rsp;
- }
- dynamic expandoObject = new ExpandoObject();
- foreach (var prop in type.GetProperties())
- {
- var alias = prop.GetCustomAttribute<AliasAsAttribute>();
- ((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<IQuickApiExceptionHandler>();
- //异常处理
- 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<IQuickApiExceptionHandler>();
- //异常处理
- foreach (var handler in exceptionHandlers)
- {
- await handler.HandleAsync(ex);
- }
- //默认处理
- throw;
- }
- ```这个就爽歪歪了 反射的问题没有了 动态类型也不见了 性能直接提升了 !
- 最后 Gen的实现代码可以翻看.
- https://github.com/vipwan/Biwen.QuickApi 这里就不赘述了.
- 欢迎 star 交流 ~
复制代码 来源:https://www.cnblogs.com/vipwan/archive/2023/09/27/biwen-quickapi-gen.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|