Skip to content

Commit

Permalink
✨ Ipc 元组支持
Browse files Browse the repository at this point in the history
  • Loading branch information
AigioL committed Dec 18, 2023
1 parent bdb7257 commit fffb522
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 7 deletions.
5 changes: 2 additions & 3 deletions src/AssemblyLoad.Sample.EntryPoint/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
Console.WriteLine($"Environment.Version: {Environment.Version}");
// 从低版本的运行时中加载高版本的程序集
var libPath = string.Join(Path.DirectorySeparatorChar.ToString(),
new string[]
{
[
ProjPath.TrimEnd(Path.DirectorySeparatorChar),
"src",
"artifacts",
"bin",
"AssemblyLoad.Sample.Library",
"debug",
"AssemblyLoad.Sample.Library.dll",
});
]);
var assembly = Assembly.LoadFile(libPath);
var program = assembly.GetType("AssemblyLoad.Sample.Library.Program", true);
var main = program.GetMethod("Main", BindingFlags.Static | BindingFlags.NonPublic);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ public static MethodParametersCategory GetMethodParametersCategory(this IMethodS
else if (method.Parameters.Length == 2 &&
new TypeStringImpl(method.Parameters[1].Type).IsSystemThreadingCancellationToken)
return MethodParametersCategory.FromBody;
return MethodParametersCategory.GeneratorModelFromBody;
if (method.Parameters.Length <= 21 ||
(method.Parameters.Length == 22 &&
new TypeStringImpl(method.Parameters[21].Type).IsSystemThreadingCancellationToken))
return MethodParametersCategory.GeneratorModelFromBody; // global::System.TupleExtensions.ToTuple 泛型仅支持最多 21 个参数
return MethodParametersCategory.None;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,40 @@ MethodParametersCategory.FromBody or
};
return requestMethod;
}

/// <summary>
/// 写入 <see cref="Tuple"/>
/// </summary>
/// <param name="stream"></param>
/// <param name="methodParas"></param>
protected void WriteTuple(Stream stream, MethodPara[] methodParas)
{
Tuple<int, int, int, int, int, int, int, Tuple<int, int>> a = default;
int endLen = 0;
for (int i = 0; i < methodParas.Length; i++)
{
var (paraType, _, _) = methodParas[i];
if (i == methodParas.Length - 1)
{
if (paraType.IsSystemThreadingCancellationToken)
{
break;
}
}
if (i != 0)
{
stream.Write(", "u8);
}
if (i % 7 == 0)
{
stream.Write("Tuple<"u8);
endLen++;
}
stream.WriteUtf16StrToUtf8OrCustom(paraType.ToString());
}
for (int i = 0; i < endLen; i++)
{
stream.Write(">"u8);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ void WriteMethodBodyWithWebApi()
"""u8, methodParas[0].ParaType);
break;
case MethodParametersCategory.GeneratorModelFromBody:
stream.Write(", "u8);
WriteTuple(stream, methodParas);
break;
}

Expand Down Expand Up @@ -309,6 +311,59 @@ void WriteMethodBodyWithWebApi()
}
break;
case MethodParametersCategory.GeneratorModelFromBody:
stream.Write(
"""
, global::System.TupleExtensions.ToTuple<
"""u8);
for (int i = 0; i < methodParas.Length; i++)
{
var (paraType, _, _) = methodParas[i];
if (i == methodParas.Length - 1)
{
if (paraType.IsSystemThreadingCancellationToken)
{
break;
}
}
if (i != 0)
{
stream.Write(
"""
,
"""u8);
}
stream.WriteUtf16StrToUtf8OrCustom(paraType.ToString());
}
stream.Write(
"""
>((
"""u8);
for (int i = 0; i < methodParas.Length; i++)
{
var (paraType, paraName, _) = methodParas[i];
if (i == methodParas.Length - 1)
{
if (paraType.IsSystemThreadingCancellationToken)
{
break;
}
}
if (i == 0)
{
stream.WriteUtf16StrToUtf8OrCustom(paraName);
}
else
{
stream.WriteFormat(
"""
, {0}
"""u8, paraName);
}
}
stream.Write(
"""
)), cancellationToken: cancellationToken
"""u8);
break;
}

Expand Down
18 changes: 18 additions & 0 deletions src/BD.Common8.SourceGenerator.Ipc.Server.Test/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,22 @@ public Task<ApiRspImpl> SimpleTypes(bool p0, byte p1, sbyte p2, char p3, DateOnl
{
throw new NotImplementedException();
}

Task<ApiRspImpl> ITodoService.Tuple(bool p0, byte p1, sbyte p2, char p3, DateOnly p4, DateTime p5, DateTimeOffset p6, decimal p7, double p8, ProcessorArchitecture[] p9, Guid p10, short p11, int p12, long p13, float p14, TimeOnly p15, TimeSpan p16, ushort p17, uint p18, ulong[] p19, Uri p20, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}

/// <inheritdoc cref="IEndpointRouteMapGroup.OnMapGroup(IEndpointRouteBuilder)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void OnMapGroup(IEndpointRouteBuilder endpoints)
{
var builder = endpoints.MapGroup("/ITodoService").RequireAuthorization();
builder.MapGet("/All", (Delegate)(static async (HttpContext ctx) => await Ioc.Get<ITodoService>().All(ctx.RequestAborted)));
builder.MapGet("/GetById/{id}", (Delegate)(static async (HttpContext ctx, [FromRoute] int id) => await Ioc.Get<ITodoService>().GetById(id, ctx.RequestAborted)));
builder.MapGet("/SimpleTypes/{p0}/{p1}/{p2}/{p3}/{p4}/{p5}/{p6}/{p7}/{p8}/{p9}/{p10}/{p11}/{p12}/{p13}/{p14}/{p15}/{p16}/{p17}/{p18}/{p19}/{p20}/{p21}", (Delegate)(static async (HttpContext ctx, [FromRoute] bool p0, [FromRoute] byte p1, [FromRoute] sbyte p2, [FromRoute] char p3, [FromRoute] DateOnly p4, [FromRoute] DateTime p5, [FromRoute] DateTimeOffset p6, [FromRoute] decimal p7, [FromRoute] double p8, [FromRoute] ProcessorArchitecture p9, [FromRoute] Guid p10, [FromRoute] short p11, [FromRoute] int p12, [FromRoute] long p13, [FromRoute] float p14, [FromRoute] TimeOnly p15, [FromRoute] TimeSpan p16, [FromRoute] ushort p17, [FromRoute] uint p18, [FromRoute] ulong p19, [FromRoute] Uri p20, [FromRoute] Version p21) => await Ioc.Get<ITodoService>().SimpleTypes(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, ctx.RequestAborted)));
builder.MapPost("/BodyTest", (Delegate)(static async (HttpContext ctx, [FromBody] Tuple<Todo> body) => await Ioc.Get<ITodoService>().BodyTest(todo, ctx.RequestAborted)));
builder.MapGet("/AsyncEnumerable/{len}", (Delegate)(static (HttpContext ctx, [FromRoute] int len) => Ioc.Get<ITodoService>().AsyncEnumerable(len, ctx.RequestAborted)));
builder.MapPost("/Tuple", (Delegate)(static async (HttpContext ctx, [FromBody] Tuple<bool, byte, sbyte, char, DateOnly, DateTime, DateTimeOffset, Tuple<decimal, double, ProcessorArchitecture[], Guid, short, int, long, Tuple<float, TimeOnly, TimeSpan, ushort, uint, ulong[], Uri>>> body) => await Ioc.Get<ITodoService>().Tuple(body.Item1, body.Item2, body.Item3, body.Item4, body.Item5, body.Item6, body.Item7, body.Rest.Item1, body.Rest.Item2, body.Rest.Item3, body.Rest.Item4, body.Rest.Item5, body.Rest.Item6, body.Rest.Item7, body.Rest.Rest.Item1, body.Rest.Rest.Item2, body.Rest.Rest.Item3, body.Rest.Rest.Item4, body.Rest.Rest.Item5, body.Rest.Rest.Item6, body.Rest.Rest.Item7, ctx.RequestAborted)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ static void IEndpointRouteMapGroup.OnMapGroup(IEndpointRouteBuilder endpoints)
}
break;
case MethodParametersCategory.FromBody:
case MethodParametersCategory.GeneratorModelFromBody:
{
var (paraType, paraName, _) = methodParas[0];
stream.WriteFormat(
Expand All @@ -155,6 +154,19 @@ static void IEndpointRouteMapGroup.OnMapGroup(IEndpointRouteBuilder endpoints)
"""u8, paraType, paraName);
}
break;
case MethodParametersCategory.GeneratorModelFromBody:
{
stream.Write(
"""
, [FromBody]
"""u8);
WriteTuple(stream, methodParas);
stream.Write(
"""
body
"""u8);
}
break;
}
if (isAsyncEnumerableByReturnType)
{
Expand Down Expand Up @@ -199,13 +211,47 @@ static void IEndpointRouteMapGroup.OnMapGroup(IEndpointRouteBuilder endpoints)
}
break;
case MethodParametersCategory.FromBody:
case MethodParametersCategory.GeneratorModelFromBody:
{
var (_, paraName, _) = methodParas[0];
stream.WriteUtf16StrToUtf8OrCustom(paraName);
isFirstMapMethodArg = false;
}
break;
case MethodParametersCategory.GeneratorModelFromBody:
{
for (int i = 0; i < methodParas.Length; i++)
{
var (paraType, _, _) = methodParas[i];
if (i == methodParas.Length - 1)
{
if (paraType.IsSystemThreadingCancellationToken)
{
break;
}
}

// body.Item1, body.Item2, body.Item3, body.Item4, body.Item5, body.Item6, body.Item7,
// body.Rest.Item1, body.Rest.Item2, body.Rest.Item3, body.Rest.Item4, body.Rest.Item5, body.Rest.Item6, body.Rest.Item7,
// body.Rest.Rest.Item1, body.Rest.Rest.Item2, body.Rest.Rest.Item3, body.Rest.Rest.Item4
if (i != 0)
{
stream.Write(", "u8);
}

stream.Write("body"u8);

var v = i / 7;
for (int j = 0; j < v; j++)
{
stream.Write(".Rest"u8);
}
stream.Write(".Item"u8);

stream.WriteUtf16StrToUtf8OrCustom((i - (v * 7) + 1).ToString());
}
isFirstMapMethodArg = false;
}
break;
default:
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static bool IsSimpleTypes(this ITypeSymbol typeSymbol)
if (typeSymbol.IsEnum())
return true;

switch (typeSymbol.ContainingNamespace.Name)
switch (typeSymbol.ContainingNamespace?.Name)
{
case "System":
switch (typeSymbol.Name)
Expand Down
35 changes: 35 additions & 0 deletions src/Ipc.Server.Sample.Experimental/ITodoService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,41 @@ Task<ApiRspImpl> BodyTest(Todo todo, CancellationToken cancellationToken = defau
/// <param name="cancellationToken"></param>
/// <returns></returns>
IAsyncEnumerable<Todo> AsyncEnumerable(int len, CancellationToken cancellationToken = default);

/// <summary>
/// 测试使用 <see cref="Tuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/>
/// </summary>
/// <param name="p0"></param>
/// <param name="p1"></param>
/// <param name="p2"></param>
/// <param name="p3"></param>
/// <param name="p4"></param>
/// <param name="p5"></param>
/// <param name="p6"></param>
/// <param name="p7"></param>
/// <param name="p8"></param>
/// <param name="p9"></param>
/// <param name="p10"></param>
/// <param name="p11"></param>
/// <param name="p12"></param>
/// <param name="p13"></param>
/// <param name="p14"></param>
/// <param name="p15"></param>
/// <param name="p16"></param>
/// <param name="p17"></param>
/// <param name="p18"></param>
/// <param name="p19"></param>
/// <param name="p20"></param>
/// <param name="p21"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<ApiRspImpl> Tuple(bool p0, byte p1, sbyte p2,
char p3, DateOnly p4, DateTime p5,
DateTimeOffset p6, decimal p7, double p8,
ProcessorArchitecture[] p9, Guid p10, short p11,
int p12, long p13, float p14,
TimeOnly p15, TimeSpan p16, ushort p17,
uint p18, ulong[] p19, Uri p20, CancellationToken cancellationToken = default);
}

/// <summary>
Expand Down
20 changes: 20 additions & 0 deletions src/Ipc.Server.Sample.Experimental/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ protected override void Configure(WebApplication app)
app.UseSwagger();
app.UseSwaggerUI();
}

// 测试元组 Tuple,System.Text.Json 不支持 ValueTuple
//var a = System.TupleExtensions.ToTuple((1, 2, 3));
app.MapGroup("/Test")
.MapPost("Tuple",
(Delegate)(([FromBody] Tuple<int, string, string, string, string, string, string, Tuple<string, string, string, string, string, string, string, Tuple<string, string, string, string, string, string, string>>> body) => body));
}
}

Expand Down Expand Up @@ -241,4 +247,18 @@ public async IAsyncEnumerable<Todo> AsyncEnumerable(int len, [EnumeratorCancella
yield return todos[^1]; // 超出长度返回最后一个
}
}

public async Task<ApiRspImpl> Tuple(bool p0, byte p1, sbyte p2,
char p3, DateOnly p4, DateTime p5,
DateTimeOffset p6, decimal p7, double p8,
ProcessorArchitecture[] p9, Guid p10, short p11,
int p12, long p13, float p14,
TimeOnly p15, TimeSpan p16, ushort p17,
uint p18, ulong[] p19, Uri p20, CancellationToken cancellationToken = default)
{
await Clients.All.SendAsync(nameof(ITodoService), nameof(SimpleTypes), RequestAborted());
var result = ApiRspHelper.Ok();
result.InternalMessage = $"{p0}/{p1}/{p2}/{p3}/{p4}/{p5}/{p6}/{p7}/{p8}/{string.Join(", ", p9 ?? [])}/{p10}/{p11}/{p12}/{p13}/{p14}/{p15}/{p16}/{p17}/{p18}/{string.Join(", ", p19 ?? [])}/{p20}";
return result;
}
}

0 comments on commit fffb522

Please sign in to comment.