Skip to content
Merged

Aot #253

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions App/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ public void ConfigureServices(IServiceCollection services)
services
.AddWebApiClient()
.UseJsonFirstApiActionDescriptor()
.UseSourceGeneratorHttpApiActivator()
.AddDynamicDependencyApp();
.UseSourceGeneratorHttpApiActivator();

// ע��userApi
services.AddHttpApi(typeof(IUserApi), o =>
Expand Down
24 changes: 24 additions & 0 deletions AppAot/AppAot.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Nullable>enable</Nullable>
<PublishTrimmed>true</PublishTrimmed>
<PublishAot>true</PublishAot>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\WebApiClientCore.Extensions.SourceGenerator\WebApiClientCore.Extensions.SourceGenerator.csproj" />
<ProjectReference Include="..\WebApiClientCore\WebApiClientCore.csproj" />
<ProjectReference Include="..\WebApiClientCore.Analyzers\WebApiClientCore.Analyzers.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<ProjectReference Include="..\WebApiClientCore.Analyzers.SourceGenerator\WebApiClientCore.Analyzers.SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>

</Project>
7 changes: 7 additions & 0 deletions AppAot/AppData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace AppAot
{
public class AppData
{
public string? WebpackCompilationHash { get; set; }
}
}
35 changes: 35 additions & 0 deletions AppAot/AppHostedService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
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<AppHostedService> logger;

public AppHostedService(
IServiceScopeFactory serviceScopeFactory,
ILogger<AppHostedService> 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<ICloudflareApi>();
var appData = await api.GetAppDataAsync();
appData = await api.GetAppData2Async();
this.logger.LogInformation($"WebpackCompilationHash: {appData.WebpackCompilationHash}");
}
}
}
9 changes: 9 additions & 0 deletions AppAot/AppJsonSerializerContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Text.Json.Serialization;

namespace AppAot
{
[JsonSerializable(typeof(AppData[]))]
partial class AppJsonSerializerContext : JsonSerializerContext
{
}
}
17 changes: 17 additions & 0 deletions AppAot/ICloudflareApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Threading.Tasks;
using WebApiClientCore;
using WebApiClientCore.Attributes;

namespace AppAot
{
[HttpHost("https://www.cloudflare-cn.com")]
[LoggingFilter]
public interface ICloudflareApi
{
[HttpGet("/page-data/app-data.json")]
Task<AppData> GetAppDataAsync();

[HttpGet("/page-data/app-data.json")]
ITask<AppData> GetAppData2Async();
}
}
31 changes: 31 additions & 0 deletions AppAot/Program.cs
Original file line number Diff line number Diff line change
@@ -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<ICloudflareApi>();
services.AddHostedService<AppHostedService>();
})
.Build()
.Run();
}
}
}
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<Version>2.0.5</Version>
<Copyright>Copyright © laojiu 2017-2023</Copyright>
<Version>2.0.6</Version>
<Copyright>Copyright © laojiu 2017-2024</Copyright>
<NoWarn>IDE0057</NoWarn>
</PropertyGroup>

Expand Down
6 changes: 5 additions & 1 deletion WebApiClientCore.Abstractions/IHttpApiActivator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
/// 定义THttpApi的实例创建器的接口
/// </summary>
/// <typeparam name="THttpApi"></typeparam>
public interface IHttpApiActivator<THttpApi>
public interface IHttpApiActivator<
#if NET5_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)]
#endif
THttpApi>
{
/// <summary>
/// 创建THttpApi的代理实例
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<Nullable>enable</Nullable>
<TargetFramework>netstandard2.1</TargetFramework>
<TargetFrameworks>netstandard2.1;net5.0</TargetFrameworks>

<RootNamespace>WebApiClientCore</RootNamespace>
<AssemblyName>WebApiClientCore.Abstractions</AssemblyName>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ sealed class DynamicDependencyBuilder
private readonly Compilation compilation;
private readonly IEnumerable<HttpApiCodeBuilder> 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<HttpApiCodeBuilder> codeBuilders)
{
Expand All @@ -35,47 +35,41 @@ 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.Implementations");
builder.AppendLine("{");
builder.AppendLine(" /// <summary>IWebApiClientBuilder扩展</summary>");
builder.AppendLine($" public static partial class {this.ClassName}");
builder.AppendLine(" /// <summary>动态依赖初始化器</summary>");
builder.AppendLine($" static partial class {this.ClassName}");
builder.AppendLine(" {");

builder.AppendLine($"""
/// <summary>
/// 注册程序集{compilation.AssemblyName}的所有动态依赖
/// 避免程序集在裁剪时裁剪掉由SourceGenerator生成的代理类
/// </summary>
/// <param name="builder"></param>
/// <returns></returns>
""");

var assemblyName = GetAssemblyName(compilation);
builder.AppendLine(" [ModuleInitializer]");
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)");
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(" 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');
}
}
}
}
16 changes: 16 additions & 0 deletions WebApiClientCore.Analyzers.SourceGenerator/HttpApiCodeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,22 @@ public override string ToString()
}


public IEnumerable<ITypeSymbol> 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;
}
}
}
}

/// <summary>
/// 构建方法
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ namespace WebApiClientCore.Implementations
/// 通过查找类型代理类型创建实例
/// </summary>
/// <typeparam name="THttpApi"></typeparam>
public class SourceGeneratorHttpApiActivator<THttpApi> : IHttpApiActivator<THttpApi>
public class SourceGeneratorHttpApiActivator<
#if NET5_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)]
#endif
THttpApi> : IHttpApiActivator<THttpApi>
{
private readonly ApiActionInvoker[] actionInvokers;
private readonly Func<IHttpApiInterceptor, ApiActionInvoker[], THttpApi> activator;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Version>2.0.5.1</Version>
<PropertyGroup>
<Nullable>enable</Nullable>
<TargetFramework>netstandard2.1</TargetFramework>
<TargetFrameworks>netstandard2.1;net5.0</TargetFrameworks>
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>

<SignAssembly>true</SignAssembly>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Version>2.0.4.1</Version>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1;net5;net6;net7</TargetFrameworks>

Expand Down
6 changes: 6 additions & 0 deletions WebApiClientCore.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions WebApiClientCore/Implementations/DefaultApiActionInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public virtual async Task<TResult> 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)
{
Expand All @@ -83,7 +83,7 @@ public virtual async Task<TResult> InvokeAsync(HttpClientContext context, object
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
private async Task<TResult> InvokeAsync(ApiRequestContext request)
private static async Task<TResult> InvokeAsync(ApiRequestContext request)
{
#nullable disable
var response = await ApiRequestExecuter.ExecuteAsync(request).ConfigureAwait(false);
Expand Down Expand Up @@ -136,7 +136,7 @@ public ITaskReturnActionInvoker(DefaultApiActionInvoker<TResult> actionInvoker)
public override object Invoke(HttpClientContext context, object?[] arguments)
{
return new ActionTask<TResult>(this.actionInvoker, context, arguments);
}
}
}
}
}
6 changes: 5 additions & 1 deletion WebApiClientCore/Implementations/DefaultHttpApiActivator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ namespace WebApiClientCore.Implementations
/// 运行时使用Emit动态创建THttpApi的代理类和代理类实例
/// </summary>
/// <typeparam name="THttpApi"></typeparam>
public class DefaultHttpApiActivator<THttpApi> : IHttpApiActivator<THttpApi>
public class DefaultHttpApiActivator<
#if NET5_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)]
#endif
THttpApi> : IHttpApiActivator<THttpApi>
{
private readonly ApiActionInvoker[] actionInvokers;
private readonly Func<IHttpApiInterceptor, ApiActionInvoker[], THttpApi> activator;
Expand Down
2 changes: 1 addition & 1 deletion WebApiClientCore/Resx.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading