无需编码,自动实现“异步 Request-Reply”模式
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无需编码,自动实现“异步 Request-Reply”模式相关的知识,希望对你有一定的参考价值。
前言
上次,我们虽然用代码实现了“异步 Request-Reply 模式”,但是需要为每一个长时间操作 API 实现一个对应的 AsyncXXX 操作。
其实,可以尝试用 Source Generators 减少这种重复性劳动。
实现思路
Controller 类必须是
partial
,这样才能为它额外增加新方法;为每个长时间操作 API 声明一个 AsyncMethodAttribute,这样 Source Generators 才知道为谁实现对应的同步操作;
遍历所有声明了 AsyncMethodAttribute 的方法,为其编写实现方法。
具体代码
1.添加 AsyncMethodAttribute
向待编译项目加入 AsyncMethodAttribute 代码:
const string asyncMethodAttributeText = @"using System;
namespace AsyncMethodGenerator
public sealed class AsyncMethodAttribute : Attribute
public AsyncMethodAttribute()
";
context.AddSource("AsyncMethodAttribute", SourceText.From(asyncMethodAttributeText, Encoding.UTF8));
2.遍历 AsyncMethodAttribute 声明方法
找到声明了 AsyncMethodAttribute 的所有方法:
private string GenerateMethods(SyntaxList<MemberDeclarationSyntax> members)
StringBuilder stringBuilder = new StringBuilder();
foreach (var member in members)
if(member is MethodDeclarationSyntax method && HasAsyncMethodAttribute(method))
stringBuilder.Append(GenerateAsyncMethod(method));
return stringBuilder.ToString();
private bool HasAsyncMethodAttribute(MethodDeclarationSyntax method)
var hasAttribute = false;
foreach (var attributeList in method.AttributeLists)
foreach (var attribute in attributeList.Attributes)
if (attribute.Name.ToString().Equals("AsyncMethod"))
hasAttribute = true;
return hasAttribute;
3.生成 AsyncMethod 代码
根据原方法定义,生成 AsyncMethod 方法:
private string GenerateAsyncMethod(MethodDeclarationSyntax method)
var stringBuilder = new StringBuilder();
foreach (var attributeList in method.AttributeLists)
foreach (var attribute in attributeList.Attributes)
if (attribute.Name.ToString().Equals("Route"))
stringBuilder.Append($@"[Route(""async/attribute.ArgumentList.Arguments[0].ToString().Trim('"')"")]");
else
stringBuilder.Append($"[attribute]");
stringBuilder.Append("\\r\\n");
stringBuilder.Append($"public async Task<IActionResult> Asyncmethod.Identifier ");
stringBuilder.Append($"(method.ParameterList.Parameters)");
stringBuilder.Append("\\r\\n");
stringBuilder.Append($@"
string id = Guid.NewGuid().ToString();
string responseValue = $@""/status/id"";
_cache.SetString(id, responseValue);
Task.Factory.StartNew(() =>
var result = GenerateCallingMethod(method).Result;
_cache.SetString(id + ""_result"", JsonConvert.SerializeObject(result));
);
return Accepted(responseValue);
");
return stringBuilder.ToString();
4.使用
现在,就可以在目标项目中使用 AsyncMethod 方法了:
[ApiController]
[Route("[controller]")]
public partial class WeatherForecastController : ControllerBase
...
[HttpGet]
[Route("get")]
[AsyncMethod]
public async Task<IEnumerable<WeatherForecast>> Get()
...
注意 WeatherForecastController 是 partial class
结论
有了 Source Generators,可以让编译器帮我们自动实现“异步 Request-Reply 模式”了!
想了解更多内容,请关注我的个人公众号”My IO“
以上是关于无需编码,自动实现“异步 Request-Reply”模式的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch:通过热温冷和冻结层管理数据自动化 — 无需编码!
Elasticsearch:通过热温冷和冻结层管理数据自动化 — 无需编码!
GitHub 近两万 Star,无需编码,可一键生成前后端代码,开源项目