From 347a6277e5c3f6379adf69f4762a143dfab52c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=9B=BD=E4=BC=9F?= <366193849@qq.com> Date: Tue, 28 May 2024 14:51:19 +0800 Subject: [PATCH 1/3] =?UTF-8?q?aot=E5=AE=9E=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App/Startup.cs | 3 +- AppAot/AppAot.csproj | 24 +++++++++++++ AppAot/AppData.cs | 7 ++++ AppAot/AppHostedService.cs | 34 +++++++++++++++++++ AppAot/AppJsonSerializerContext.cs | 9 +++++ AppAot/ICloudflareApi.cs | 13 +++++++ AppAot/Program.cs | 31 +++++++++++++++++ .../IHttpApiActivator.cs | 6 +++- .../WebApiClientCore.Abstractions.csproj | 2 +- .../DynamicDependencyBuilder.cs | 33 +++++------------- .../HttpApiSourceGenerator.cs | 10 ++++-- .../SourceGeneratorHttpApiActivator.cs | 6 +++- ...ientCore.Extensions.SourceGenerator.csproj | 5 ++- ...iClientCore.OpenApi.SourceGenerator.csproj | 3 +- WebApiClientCore.sln | 6 ++++ .../DefaultApiActionInvoker.cs | 6 +++- .../DefaultHttpApiActivator.cs | 6 +++- WebApiClientCore/Resx.Designer.cs | 2 +- WebApiClientCore/WebApiClientCore.csproj | 2 +- 19 files changed, 167 insertions(+), 41 deletions(-) create mode 100644 AppAot/AppAot.csproj create mode 100644 AppAot/AppData.cs create mode 100644 AppAot/AppHostedService.cs create mode 100644 AppAot/AppJsonSerializerContext.cs create mode 100644 AppAot/ICloudflareApi.cs create mode 100644 AppAot/Program.cs diff --git a/App/Startup.cs b/App/Startup.cs index 4b4486d4..544b307a 100644 --- a/App/Startup.cs +++ b/App/Startup.cs @@ -49,8 +49,7 @@ public void ConfigureServices(IServiceCollection services) services .AddWebApiClient() .UseJsonFirstApiActionDescriptor() - .UseSourceGeneratorHttpApiActivator() - .AddDynamicDependencyApp(); + .UseSourceGeneratorHttpApiActivator(); // עuserApi services.AddHttpApi(typeof(IUserApi), o => diff --git a/AppAot/AppAot.csproj b/AppAot/AppAot.csproj new file mode 100644 index 00000000..b949817e --- /dev/null +++ b/AppAot/AppAot.csproj @@ -0,0 +1,24 @@ + + + + Exe + net8.0 + false + enable + true + true + true + + + + + + + + + + + + + + diff --git a/AppAot/AppData.cs b/AppAot/AppData.cs new file mode 100644 index 00000000..69b21421 --- /dev/null +++ b/AppAot/AppData.cs @@ -0,0 +1,7 @@ +namespace AppAot +{ + public class AppData + { + public string? WebpackCompilationHash { get; set; } + } +} diff --git a/AppAot/AppHostedService.cs b/AppAot/AppHostedService.cs new file mode 100644 index 00000000..6c3a7aba --- /dev/null +++ b/AppAot/AppHostedService.cs @@ -0,0 +1,34 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace AppAot +{ + class AppHostedService : BackgroundService + { + private readonly IServiceScopeFactory serviceScopeFactory; + private readonly ILogger logger; + + public AppHostedService( + IServiceScopeFactory serviceScopeFactory, + ILogger logger) + { + this.serviceScopeFactory = serviceScopeFactory; + this.logger = logger; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + using var scope = this.serviceScopeFactory.CreateScope(); + var api = scope.ServiceProvider.GetRequiredService(); + var appData = await api.GetAppDataAsync(); + this.logger.LogInformation($"WebpackCompilationHash: {appData.WebpackCompilationHash}"); + } + } +} diff --git a/AppAot/AppJsonSerializerContext.cs b/AppAot/AppJsonSerializerContext.cs new file mode 100644 index 00000000..f64fe137 --- /dev/null +++ b/AppAot/AppJsonSerializerContext.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace AppAot +{ + [JsonSerializable(typeof(AppData[]))] + partial class AppJsonSerializerContext : JsonSerializerContext + { + } +} diff --git a/AppAot/ICloudflareApi.cs b/AppAot/ICloudflareApi.cs new file mode 100644 index 00000000..739db202 --- /dev/null +++ b/AppAot/ICloudflareApi.cs @@ -0,0 +1,13 @@ +using System.Threading.Tasks; +using WebApiClientCore.Attributes; + +namespace AppAot +{ + [HttpHost("https://www.cloudflare-cn.com")] + [LoggingFilter] + public interface ICloudflareApi + { + [HttpGet("/page-data/app-data.json")] + Task GetAppDataAsync(); + } +} diff --git a/AppAot/Program.cs b/AppAot/Program.cs new file mode 100644 index 00000000..79711d1f --- /dev/null +++ b/AppAot/Program.cs @@ -0,0 +1,31 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace AppAot +{ + class Program + { + static void Main(string[] args) + { + Host.CreateDefaultBuilder(args) + .ConfigureServices(services => + { + services + .AddWebApiClient() + .UseSourceGeneratorHttpApiActivator() // SG 激活器 + .ConfigureHttpApi(options => // json SG生成器配置 + { + var jsonContext = AppJsonSerializerContext.Default; + options.JsonSerializeOptions.TypeInfoResolverChain.Insert(0, jsonContext); + options.JsonDeserializeOptions.TypeInfoResolverChain.Insert(0, jsonContext); + options.KeyValueSerializeOptions.GetJsonSerializerOptions().TypeInfoResolverChain.Insert(0, jsonContext); + }); + + services.AddHttpApi(); + services.AddHostedService(); + }) + .Build() + .Run(); + } + } +} diff --git a/WebApiClientCore.Abstractions/IHttpApiActivator.cs b/WebApiClientCore.Abstractions/IHttpApiActivator.cs index f2a07542..758c807e 100644 --- a/WebApiClientCore.Abstractions/IHttpApiActivator.cs +++ b/WebApiClientCore.Abstractions/IHttpApiActivator.cs @@ -4,7 +4,11 @@ /// 定义THttpApi的实例创建器的接口 /// /// - public interface IHttpApiActivator + public interface IHttpApiActivator< +#if NET5_0_OR_GREATER + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] +#endif + THttpApi> { /// /// 创建THttpApi的代理实例 diff --git a/WebApiClientCore.Abstractions/WebApiClientCore.Abstractions.csproj b/WebApiClientCore.Abstractions/WebApiClientCore.Abstractions.csproj index fab7a852..579f5112 100644 --- a/WebApiClientCore.Abstractions/WebApiClientCore.Abstractions.csproj +++ b/WebApiClientCore.Abstractions/WebApiClientCore.Abstractions.csproj @@ -2,7 +2,7 @@ enable - netstandard2.1 + netstandard2.1;net5.0 WebApiClientCore WebApiClientCore.Abstractions diff --git a/WebApiClientCore.Analyzers.SourceGenerator/DynamicDependencyBuilder.cs b/WebApiClientCore.Analyzers.SourceGenerator/DynamicDependencyBuilder.cs index 7504abcc..719c2def 100644 --- a/WebApiClientCore.Analyzers.SourceGenerator/DynamicDependencyBuilder.cs +++ b/WebApiClientCore.Analyzers.SourceGenerator/DynamicDependencyBuilder.cs @@ -1,7 +1,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; using System.Collections.Generic; -using System.Linq; using System.Text; namespace WebApiClientCore.Analyzers.SourceGenerator @@ -11,8 +10,8 @@ sealed class DynamicDependencyBuilder private readonly Compilation compilation; private readonly IEnumerable codeBuilders; - public string FileName => "WebApiClientBuilderExtensions.g.cs"; - public string ClassName => "WebApiClientBuilderExtensions_G"; + public string FileName => "DynamicDependencyInitializer.g.cs"; + public string ClassName => "DynamicDependencyInitializer_G"; public DynamicDependencyBuilder(Compilation compilation, IEnumerable codeBuilders) { @@ -35,10 +34,11 @@ public override string ToString() var builder = new StringBuilder(); builder.AppendLine("#if NET5_0_OR_GREATER"); builder.AppendLine("using System.Diagnostics.CodeAnalysis;"); - builder.AppendLine("namespace Microsoft.Extensions.DependencyInjection"); + builder.AppendLine("using System.Runtime.CompilerServices;"); + builder.AppendLine($"namespace WebApiClientCore"); builder.AppendLine("{"); - builder.AppendLine(" /// IWebApiClientBuilder扩展"); - builder.AppendLine($" public static partial class {this.ClassName}"); + builder.AppendLine(" /// 动态依赖初始化器"); + builder.AppendLine($" static partial class {this.ClassName}"); builder.AppendLine(" {"); builder.AppendLine($""" @@ -46,36 +46,21 @@ public override string ToString() /// 注册程序集{compilation.AssemblyName}的所有动态依赖 /// 避免程序集在裁剪时裁剪掉由SourceGenerator生成的代理类 /// - /// - /// """); - - var assemblyName = GetAssemblyName(compilation); foreach (var codeBuilder in this.codeBuilders) { builder.AppendLine($" [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof({codeBuilder.Namespace}.{codeBuilder.ClassName}))]"); } - - builder.AppendLine($" public static IWebApiClientBuilder AddDynamicDependency{assemblyName}(this IWebApiClientBuilder builder)"); + builder.AppendLine(" [ModuleInitializer]"); + builder.AppendLine(" public static void AddDynamicDependency()"); builder.AppendLine(" {"); - builder.AppendLine(" return builder;"); builder.AppendLine(" }"); - + builder.AppendLine(" }"); builder.AppendLine("}"); builder.AppendLine("#endif"); return builder.ToString(); } - private static string GetAssemblyName(Compilation compilation) - { - var assemblyName = compilation.AssemblyName ?? string.Empty; - return new string(assemblyName.Where(IsAllowChar).ToArray()); - - static bool IsAllowChar(char c) - { - return ('0' <= c && c <= '9') || ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'); - } - } } } diff --git a/WebApiClientCore.Analyzers.SourceGenerator/HttpApiSourceGenerator.cs b/WebApiClientCore.Analyzers.SourceGenerator/HttpApiSourceGenerator.cs index df89ed50..b72a6cb9 100644 --- a/WebApiClientCore.Analyzers.SourceGenerator/HttpApiSourceGenerator.cs +++ b/WebApiClientCore.Analyzers.SourceGenerator/HttpApiSourceGenerator.cs @@ -29,15 +29,19 @@ public void Execute(GeneratorExecutionContext context) var builders = receiver .GetHttpApiTypes(context.Compilation) .Select(i => new HttpApiCodeBuilder(i)) - .Distinct(); + .Distinct() + .ToArray(); foreach (var builder in builders) { context.AddSource(builder.HttpApiTypeName, builder.ToSourceText()); } - var dependencyBuilder = new DynamicDependencyBuilder(context.Compilation, builders); - context.AddSource(dependencyBuilder.FileName, dependencyBuilder.ToSourceText()); + if (builders.Length > 0) + { + var dependencyBuilder = new DynamicDependencyBuilder(context.Compilation, builders); + context.AddSource(dependencyBuilder.FileName, dependencyBuilder.ToSourceText()); + } } } } diff --git a/WebApiClientCore.Extensions.SourceGenerator/Implementations/SourceGeneratorHttpApiActivator.cs b/WebApiClientCore.Extensions.SourceGenerator/Implementations/SourceGeneratorHttpApiActivator.cs index f6447ac1..2dc66668 100644 --- a/WebApiClientCore.Extensions.SourceGenerator/Implementations/SourceGeneratorHttpApiActivator.cs +++ b/WebApiClientCore.Extensions.SourceGenerator/Implementations/SourceGeneratorHttpApiActivator.cs @@ -10,7 +10,11 @@ namespace WebApiClientCore.Implementations /// 通过查找类型代理类型创建实例 /// /// - public class SourceGeneratorHttpApiActivator : IHttpApiActivator + public class SourceGeneratorHttpApiActivator< +#if NET5_0_OR_GREATER + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] +#endif + THttpApi> : IHttpApiActivator { private readonly ApiActionInvoker[] actionInvokers; private readonly Func activator; diff --git a/WebApiClientCore.Extensions.SourceGenerator/WebApiClientCore.Extensions.SourceGenerator.csproj b/WebApiClientCore.Extensions.SourceGenerator/WebApiClientCore.Extensions.SourceGenerator.csproj index 1d23058b..fb717eb7 100644 --- a/WebApiClientCore.Extensions.SourceGenerator/WebApiClientCore.Extensions.SourceGenerator.csproj +++ b/WebApiClientCore.Extensions.SourceGenerator/WebApiClientCore.Extensions.SourceGenerator.csproj @@ -1,9 +1,8 @@ - - 2.0.5.1 + enable - netstandard2.1 + netstandard2.1;net5.0 bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml true diff --git a/WebApiClientCore.OpenApi.SourceGenerator/WebApiClientCore.OpenApi.SourceGenerator.csproj b/WebApiClientCore.OpenApi.SourceGenerator/WebApiClientCore.OpenApi.SourceGenerator.csproj index b780f630..e716c31f 100644 --- a/WebApiClientCore.OpenApi.SourceGenerator/WebApiClientCore.OpenApi.SourceGenerator.csproj +++ b/WebApiClientCore.OpenApi.SourceGenerator/WebApiClientCore.OpenApi.SourceGenerator.csproj @@ -1,7 +1,6 @@  - - 2.0.4.1 + Exe netcoreapp3.1;net5;net6;net7 diff --git a/WebApiClientCore.sln b/WebApiClientCore.sln index ddd1a0c1..49d05c4b 100644 --- a/WebApiClientCore.sln +++ b/WebApiClientCore.sln @@ -27,6 +27,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApiClientCore.Extensions EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebApiClientCore.Analyzers.SourceGenerator", "WebApiClientCore.Analyzers.SourceGenerator\WebApiClientCore.Analyzers.SourceGenerator.csproj", "{DFE35D63-0888-4EE2-A9F1-AC45756F5909}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppAot", "AppAot\AppAot.csproj", "{F77DA016-1F63-46BF-A5A0-AD4662D528B9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -81,6 +83,10 @@ Global {DFE35D63-0888-4EE2-A9F1-AC45756F5909}.Debug|Any CPU.Build.0 = Debug|Any CPU {DFE35D63-0888-4EE2-A9F1-AC45756F5909}.Release|Any CPU.ActiveCfg = Release|Any CPU {DFE35D63-0888-4EE2-A9F1-AC45756F5909}.Release|Any CPU.Build.0 = Release|Any CPU + {F77DA016-1F63-46BF-A5A0-AD4662D528B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F77DA016-1F63-46BF-A5A0-AD4662D528B9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F77DA016-1F63-46BF-A5A0-AD4662D528B9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F77DA016-1F63-46BF-A5A0-AD4662D528B9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/WebApiClientCore/Implementations/DefaultApiActionInvoker.cs b/WebApiClientCore/Implementations/DefaultApiActionInvoker.cs index 6f4faaa0..017e9996 100644 --- a/WebApiClientCore/Implementations/DefaultApiActionInvoker.cs +++ b/WebApiClientCore/Implementations/DefaultApiActionInvoker.cs @@ -13,7 +13,11 @@ namespace WebApiClientCore.Implementations /// /// [DebuggerDisplay("Member = {ActionDescriptor.Member}")] - public class DefaultApiActionInvoker : ApiActionInvoker, IITaskReturnConvertable + public class DefaultApiActionInvoker< +#if NET5_0_OR_GREATER + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] +#endif + TResult> : ApiActionInvoker, IITaskReturnConvertable { /// /// 获取Action描述 diff --git a/WebApiClientCore/Implementations/DefaultHttpApiActivator.cs b/WebApiClientCore/Implementations/DefaultHttpApiActivator.cs index ce6a9adb..de7f6c5f 100644 --- a/WebApiClientCore/Implementations/DefaultHttpApiActivator.cs +++ b/WebApiClientCore/Implementations/DefaultHttpApiActivator.cs @@ -11,7 +11,11 @@ namespace WebApiClientCore.Implementations /// 运行时使用Emit动态创建THttpApi的代理类和代理类实例 /// /// - public class DefaultHttpApiActivator : IHttpApiActivator + public class DefaultHttpApiActivator< +#if NET5_0_OR_GREATER + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] +#endif + THttpApi> : IHttpApiActivator { private readonly ApiActionInvoker[] actionInvokers; private readonly Func activator; diff --git a/WebApiClientCore/Resx.Designer.cs b/WebApiClientCore/Resx.Designer.cs index 02acfbf2..81971bf8 100644 --- a/WebApiClientCore/Resx.Designer.cs +++ b/WebApiClientCore/Resx.Designer.cs @@ -19,7 +19,7 @@ namespace WebApiClientCore { // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen // (以 /str 作为命令选项),或重新生成 VS 项目。 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resx { diff --git a/WebApiClientCore/WebApiClientCore.csproj b/WebApiClientCore/WebApiClientCore.csproj index 2bbabbf8..d2585c3d 100644 --- a/WebApiClientCore/WebApiClientCore.csproj +++ b/WebApiClientCore/WebApiClientCore.csproj @@ -2,7 +2,7 @@ enable - netstandard2.1 + netstandard2.1;net5.0 bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml .NetCore声明式的Http客户端库 From 33506f144f21d93b5db347d595a87030b1fd1d84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=9B=BD=E4=BC=9F?= <366193849@qq.com> Date: Tue, 28 May 2024 16:48:42 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=AE=8C=E6=95=B4=E5=AE=9E=E7=8E=B0AOT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AppAot/AppHostedService.cs | 1 + AppAot/ICloudflareApi.cs | 4 ++++ AppAot/Program.cs | 2 +- .../IHttpApiActivator.cs | 2 +- .../DynamicDependencyBuilder.cs | 13 +++++++++++-- .../HttpApiCodeBuilder.cs | 16 ++++++++++++++++ .../SourceGeneratorHttpApiActivator.cs | 2 +- .../Implementations/DefaultApiActionInvoker.cs | 12 ++++-------- .../Implementations/DefaultHttpApiActivator.cs | 2 +- 9 files changed, 40 insertions(+), 14 deletions(-) diff --git a/AppAot/AppHostedService.cs b/AppAot/AppHostedService.cs index 6c3a7aba..eb43c58c 100644 --- a/AppAot/AppHostedService.cs +++ b/AppAot/AppHostedService.cs @@ -28,6 +28,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) using var scope = this.serviceScopeFactory.CreateScope(); var api = scope.ServiceProvider.GetRequiredService(); var appData = await api.GetAppDataAsync(); + appData = await api.GetAppData2Async(); this.logger.LogInformation($"WebpackCompilationHash: {appData.WebpackCompilationHash}"); } } diff --git a/AppAot/ICloudflareApi.cs b/AppAot/ICloudflareApi.cs index 739db202..6bdd6b7e 100644 --- a/AppAot/ICloudflareApi.cs +++ b/AppAot/ICloudflareApi.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using WebApiClientCore; using WebApiClientCore.Attributes; namespace AppAot @@ -9,5 +10,8 @@ public interface ICloudflareApi { [HttpGet("/page-data/app-data.json")] Task GetAppDataAsync(); + + [HttpGet("/page-data/app-data.json")] + ITask GetAppData2Async(); } } diff --git a/AppAot/Program.cs b/AppAot/Program.cs index 79711d1f..cb671cb9 100644 --- a/AppAot/Program.cs +++ b/AppAot/Program.cs @@ -6,7 +6,7 @@ namespace AppAot class Program { static void Main(string[] args) - { + { Host.CreateDefaultBuilder(args) .ConfigureServices(services => { diff --git a/WebApiClientCore.Abstractions/IHttpApiActivator.cs b/WebApiClientCore.Abstractions/IHttpApiActivator.cs index 758c807e..46137951 100644 --- a/WebApiClientCore.Abstractions/IHttpApiActivator.cs +++ b/WebApiClientCore.Abstractions/IHttpApiActivator.cs @@ -6,7 +6,7 @@ /// public interface IHttpApiActivator< #if NET5_0_OR_GREATER - [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] #endif THttpApi> { diff --git a/WebApiClientCore.Analyzers.SourceGenerator/DynamicDependencyBuilder.cs b/WebApiClientCore.Analyzers.SourceGenerator/DynamicDependencyBuilder.cs index 719c2def..c547c835 100644 --- a/WebApiClientCore.Analyzers.SourceGenerator/DynamicDependencyBuilder.cs +++ b/WebApiClientCore.Analyzers.SourceGenerator/DynamicDependencyBuilder.cs @@ -1,6 +1,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; using System.Collections.Generic; +using System.Linq; using System.Text; namespace WebApiClientCore.Analyzers.SourceGenerator @@ -35,7 +36,7 @@ public override string ToString() builder.AppendLine("#if NET5_0_OR_GREATER"); builder.AppendLine("using System.Diagnostics.CodeAnalysis;"); builder.AppendLine("using System.Runtime.CompilerServices;"); - builder.AppendLine($"namespace WebApiClientCore"); + builder.AppendLine($"namespace WebApiClientCore.Implementations"); builder.AppendLine("{"); builder.AppendLine(" /// 动态依赖初始化器"); builder.AppendLine($" static partial class {this.ClassName}"); @@ -47,11 +48,19 @@ public override string ToString() /// 避免程序集在裁剪时裁剪掉由SourceGenerator生成的代理类 /// """); + + builder.AppendLine(" [ModuleInitializer]"); foreach (var codeBuilder in this.codeBuilders) { builder.AppendLine($" [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof({codeBuilder.Namespace}.{codeBuilder.ClassName}))]"); } - builder.AppendLine(" [ModuleInitializer]"); + + var resultTypes = this.codeBuilders.SelectMany(item => item.GetResultTypes()).Distinct(SymbolEqualityComparer.Default); + foreach(var resultType in resultTypes) + { + builder.AppendLine($" [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(DefaultApiActionInvoker<{resultType}>))]"); + } + builder.AppendLine(" public static void AddDynamicDependency()"); builder.AppendLine(" {"); builder.AppendLine(" }"); diff --git a/WebApiClientCore.Analyzers.SourceGenerator/HttpApiCodeBuilder.cs b/WebApiClientCore.Analyzers.SourceGenerator/HttpApiCodeBuilder.cs index 1e176da3..0f281d9f 100644 --- a/WebApiClientCore.Analyzers.SourceGenerator/HttpApiCodeBuilder.cs +++ b/WebApiClientCore.Analyzers.SourceGenerator/HttpApiCodeBuilder.cs @@ -128,6 +128,22 @@ public override string ToString() } + public IEnumerable GetResultTypes() + { + var methods = HttpApiMethodFinder.FindApiMethods(this.httpApi); + foreach (var method in methods) + { + if (method.ReturnType is INamedTypeSymbol typeSymbol) + { + var resultType = typeSymbol.TypeArguments.FirstOrDefault(); + if (resultType != null) + { + yield return resultType; + } + } + } + } + /// /// 构建方法 /// diff --git a/WebApiClientCore.Extensions.SourceGenerator/Implementations/SourceGeneratorHttpApiActivator.cs b/WebApiClientCore.Extensions.SourceGenerator/Implementations/SourceGeneratorHttpApiActivator.cs index 2dc66668..3cf26bbe 100644 --- a/WebApiClientCore.Extensions.SourceGenerator/Implementations/SourceGeneratorHttpApiActivator.cs +++ b/WebApiClientCore.Extensions.SourceGenerator/Implementations/SourceGeneratorHttpApiActivator.cs @@ -12,7 +12,7 @@ namespace WebApiClientCore.Implementations /// public class SourceGeneratorHttpApiActivator< #if NET5_0_OR_GREATER - [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] #endif THttpApi> : IHttpApiActivator { diff --git a/WebApiClientCore/Implementations/DefaultApiActionInvoker.cs b/WebApiClientCore/Implementations/DefaultApiActionInvoker.cs index 017e9996..69e96633 100644 --- a/WebApiClientCore/Implementations/DefaultApiActionInvoker.cs +++ b/WebApiClientCore/Implementations/DefaultApiActionInvoker.cs @@ -13,11 +13,7 @@ namespace WebApiClientCore.Implementations /// /// [DebuggerDisplay("Member = {ActionDescriptor.Member}")] - public class DefaultApiActionInvoker< -#if NET5_0_OR_GREATER - [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] -#endif - TResult> : ApiActionInvoker, IITaskReturnConvertable + public class DefaultApiActionInvoker : ApiActionInvoker, IITaskReturnConvertable { /// /// 获取Action描述 @@ -69,7 +65,7 @@ public virtual async Task InvokeAsync(HttpClientContext context, object var httpContext = new HttpContext(context, requestMessage); var requestContext = new ApiRequestContext(httpContext, this.ActionDescriptor, arguments, new DefaultDataCollection()); - return await this.InvokeAsync(requestContext).ConfigureAwait(false); + return await InvokeAsync(requestContext).ConfigureAwait(false); } catch (HttpRequestException) { @@ -87,7 +83,7 @@ public virtual async Task InvokeAsync(HttpClientContext context, object /// /// /// - private async Task InvokeAsync(ApiRequestContext request) + private static async Task InvokeAsync(ApiRequestContext request) { #nullable disable var response = await ApiRequestExecuter.ExecuteAsync(request).ConfigureAwait(false); @@ -140,7 +136,7 @@ public ITaskReturnActionInvoker(DefaultApiActionInvoker actionInvoker) public override object Invoke(HttpClientContext context, object?[] arguments) { return new ActionTask(this.actionInvoker, context, arguments); - } + } } } } diff --git a/WebApiClientCore/Implementations/DefaultHttpApiActivator.cs b/WebApiClientCore/Implementations/DefaultHttpApiActivator.cs index de7f6c5f..51b3ede1 100644 --- a/WebApiClientCore/Implementations/DefaultHttpApiActivator.cs +++ b/WebApiClientCore/Implementations/DefaultHttpApiActivator.cs @@ -13,7 +13,7 @@ namespace WebApiClientCore.Implementations /// public class DefaultHttpApiActivator< #if NET5_0_OR_GREATER - [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] #endif THttpApi> : IHttpApiActivator { From 368c828c8df32f747be77f920e1ec67a7239e93d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=9B=BD=E4=BC=9F?= <366193849@qq.com> Date: Tue, 28 May 2024 16:58:40 +0800 Subject: [PATCH 3/3] 2.0.6 --- Directory.Build.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 26dc5f77..471696cf 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ - 2.0.5 - Copyright © laojiu 2017-2023 + 2.0.6 + Copyright © laojiu 2017-2024 IDE0057