From a6b7e8ce2320c05e4c8e6538500c4cc915d1b808 Mon Sep 17 00:00:00 2001 From: Aigio Liu Date: Fri, 9 Aug 2024 08:42:01 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20SourceGenerator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Compiler/BinaryResourceAttribute.cs | 2 +- .../Compiler/ResXGeneratedCodeAttribute.cs | 2 +- .../Helpers/IpcAppConnectionStringHelper.cs | 3 +- .../Implementation/IpcClientService.cs | 10 +- .../Services/IIpcServerService.cs | 7 - .../Implementation/IpcServerService.cs | 109 +++++---- .../Models/IpcAppConnectionString.cs | 208 +++++++++--------- .../Templates/ConstantsByPathTemplate.cs | 4 + .../Templates/CopyPropertiesTemplate.cs | 4 + .../Templates/SettingsPropertyTemplate.cs | 4 + .../Templates/SingletonPartitionTemplate.cs | 4 + .../Templates/ViewModelWrapperTemplate.cs | 4 + .../Templates/Abstractions/IpcTemplateBase.cs | 4 + .../Templates/BinaryResourceTemplate.cs | 4 + .../Templates/DesignerTemplate.cs | 4 + .../Templates/Abstractions/TemplateBase.cs | 17 +- 16 files changed, 204 insertions(+), 186 deletions(-) diff --git a/src/BD.Common8.Bcl/CodeDom/Compiler/BinaryResourceAttribute.cs b/src/BD.Common8.Bcl/CodeDom/Compiler/BinaryResourceAttribute.cs index e6da0d62a..e94587822 100644 --- a/src/BD.Common8.Bcl/CodeDom/Compiler/BinaryResourceAttribute.cs +++ b/src/BD.Common8.Bcl/CodeDom/Compiler/BinaryResourceAttribute.cs @@ -3,7 +3,7 @@ namespace System.CodeDom.Compiler; /// /// 用于标注 BD.Common8.SourceGenerator.ResX 源生成器的 ,替代 Resx 嵌入二进制资源实现零反射 /// -[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] public sealed class BinaryResourceAttribute(string args, string? appendTemplate = null) : Attribute { public string Arguments { get; init; } = args; diff --git a/src/BD.Common8.Bcl/CodeDom/Compiler/ResXGeneratedCodeAttribute.cs b/src/BD.Common8.Bcl/CodeDom/Compiler/ResXGeneratedCodeAttribute.cs index 2ae3a57ca..cf247cd55 100644 --- a/src/BD.Common8.Bcl/CodeDom/Compiler/ResXGeneratedCodeAttribute.cs +++ b/src/BD.Common8.Bcl/CodeDom/Compiler/ResXGeneratedCodeAttribute.cs @@ -3,7 +3,7 @@ namespace System.CodeDom.Compiler; /// /// 用于标注 BD.Common8.SourceGenerator.ResX 源生成器的 /// -[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] +[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] public sealed class ResXGeneratedCodeAttribute(string relativeFilePath, byte version = 0) : Attribute { /// diff --git a/src/BD.Common8.Ipc.Client/Helpers/IpcAppConnectionStringHelper.cs b/src/BD.Common8.Ipc.Client/Helpers/IpcAppConnectionStringHelper.cs index 59b61f6a6..f1c68bc44 100644 --- a/src/BD.Common8.Ipc.Client/Helpers/IpcAppConnectionStringHelper.cs +++ b/src/BD.Common8.Ipc.Client/Helpers/IpcAppConnectionStringHelper.cs @@ -22,7 +22,8 @@ public static IpcAppConnDelegatingHandler GetHttpMessageHandler(IpcAppConnection }; IpcAppConnDelegatingHandler delegatingHandler = new(connectionString, innerHandler); if (ignoreRemoteCertificateValidation) - innerHandler.SslOptions.RemoteCertificateValidationCallback = (_, _, _, _) => true; + innerHandler.SslOptions.RemoteCertificateValidationCallback = + static (_, _, _, _) => true; return delegatingHandler; } diff --git a/src/BD.Common8.Ipc.Client/Services/Implementation/IpcClientService.cs b/src/BD.Common8.Ipc.Client/Services/Implementation/IpcClientService.cs index 48570480b..8c873f598 100644 --- a/src/BD.Common8.Ipc.Client/Services/Implementation/IpcClientService.cs +++ b/src/BD.Common8.Ipc.Client/Services/Implementation/IpcClientService.cs @@ -6,7 +6,7 @@ namespace BD.Common8.Ipc.Services.Implementation; /// Ipc 客户端连接服务实现 /// /// -public partial class IpcClientService(IpcAppConnectionString connectionString) : +public abstract partial class IpcClientService(IpcAppConnectionString connectionString) : WebApiClientService(Log.Factory.CreateLogger(), null!), IIpcClientService, IAsyncDisposable { @@ -45,15 +45,11 @@ protected sealed override HttpClient CreateClient() /// https://learn.microsoft.com/zh-cn/aspnet/core/signalr/authn-and-authz?view=aspnetcore-8.0#bearer-token-authentication /// /// - protected virtual string GetAccessToken() - { - _AccessToken ??= connectionString.GetAccessToken(); - return _AccessToken; - } + protected abstract string GetAccessToken(); Task GetAccessTokenAsync() { - var accessToken = GetAccessToken(); + var accessToken = _AccessToken ??= GetAccessToken(); return Task.FromResult(accessToken)!; } diff --git a/src/BD.Common8.Ipc.Server/Services/IIpcServerService.cs b/src/BD.Common8.Ipc.Server/Services/IIpcServerService.cs index 2f4250629..fcb344151 100644 --- a/src/BD.Common8.Ipc.Server/Services/IIpcServerService.cs +++ b/src/BD.Common8.Ipc.Server/Services/IIpcServerService.cs @@ -10,11 +10,4 @@ public partial interface IIpcServerService /// /// ValueTask RunAsync(); - - /// - /// 获取用于客户端的连接字符串 - /// - /// - /// - IpcAppConnectionString GetConnectionString(IpcAppConnectionStringType type); } diff --git a/src/BD.Common8.Ipc.Server/Services/Implementation/IpcServerService.cs b/src/BD.Common8.Ipc.Server/Services/Implementation/IpcServerService.cs index d46228629..e82402851 100644 --- a/src/BD.Common8.Ipc.Server/Services/Implementation/IpcServerService.cs +++ b/src/BD.Common8.Ipc.Server/Services/Implementation/IpcServerService.cs @@ -14,7 +14,7 @@ public abstract class IpcServerService(X509Certificate2 serverCertificate) : IIp protected static void OnMapGroup(IEndpointRouteBuilder builder) => OnMapGroupEvent?.Invoke(builder); - static readonly long tickCount64 = long.MaxValue / 2; // 不可修改!!! + //static readonly long tickCount64 = long.MaxValue / 2; // 不可修改!!! WebApplication? app; @@ -204,53 +204,53 @@ static bool IsUsePort(IPAddress address, int port) // return IpcAppConnectionStringType.UnixSocket; //} - /// - public IpcAppConnectionString GetConnectionString(IpcAppConnectionStringType/*?*/ type/* = null*/) - { - if (app == null) - throw new InvalidOperationException("The service has not been started yet."); + ///// + //public IpcAppConnectionString GetConnectionString(IpcAppConnectionStringType/*?*/ type/* = null*/) + //{ + // if (app == null) + // throw new InvalidOperationException("The service has not been started yet."); - //type ??= GetFirstIpcAppConnectionStringType(); + // //type ??= GetFirstIpcAppConnectionStringType(); - switch (type/*.Value*/) - { - case IpcAppConnectionStringType.Https: - if (!ListenLocalhost) - throw new NotSupportedException( - "The current service does not support listening localhost."); - return new() - { - Type = IpcAppConnectionStringType.Https, - Int32Value = Http2Port, - TickCount64 = tickCount64, - ProcessId = Environment.ProcessId, - }; - case IpcAppConnectionStringType.UnixSocket: - if (!ListenUnixSocket) - throw new NotSupportedException( - "The current service does not support listening unix socket."); - return new() - { - Type = IpcAppConnectionStringType.UnixSocket, - StringValue = UnixSocketPath, - TickCount64 = tickCount64, - ProcessId = Environment.ProcessId, - }; - case IpcAppConnectionStringType.NamedPipe: - if (!ListenNamedPipe) - throw new NotSupportedException( - "The current service does not support listening named pipe."); - return new() - { - Type = IpcAppConnectionStringType.NamedPipe, - StringValue = PipeName, - TickCount64 = tickCount64, - ProcessId = Environment.ProcessId, - }; - default: - throw ThrowHelper.GetArgumentOutOfRangeException(type); - } - } + // switch (type/*.Value*/) + // { + // case IpcAppConnectionStringType.Https: + // if (!ListenLocalhost) + // throw new NotSupportedException( + // "The current service does not support listening localhost."); + // return new() + // { + // Type = IpcAppConnectionStringType.Https, + // Int32Value = Http2Port, + // TickCount64 = tickCount64, + // ProcessId = Environment.ProcessId, + // }; + // case IpcAppConnectionStringType.UnixSocket: + // if (!ListenUnixSocket) + // throw new NotSupportedException( + // "The current service does not support listening unix socket."); + // return new() + // { + // Type = IpcAppConnectionStringType.UnixSocket, + // StringValue = UnixSocketPath, + // TickCount64 = tickCount64, + // ProcessId = Environment.ProcessId, + // }; + // case IpcAppConnectionStringType.NamedPipe: + // if (!ListenNamedPipe) + // throw new NotSupportedException( + // "The current service does not support listening named pipe."); + // return new() + // { + // Type = IpcAppConnectionStringType.NamedPipe, + // StringValue = PipeName, + // TickCount64 = tickCount64, + // ProcessId = Environment.ProcessId, + // }; + // default: + // throw ThrowHelper.GetArgumentOutOfRangeException(type); + // } + //} /// /// 走 Http2 传输协议默认端口号,如果端口占用将随机一个新的 @@ -465,21 +465,18 @@ protected virtual void OnError(IExceptionHandlerFeature exceptionHandlerPathFeat /// https://learn.microsoft.com/zh-cn/aspnet/core/signalr/authn-and-authz?view=aspnetcore-8.0#bearer-token-authentication /// /// - protected virtual byte[] GetAccessToken() + protected abstract byte[] GetAccessToken(); + + /// + internal byte[] AccessToken { - if (_AccessToken == null) + get { - using var stream = new MemoryStream(); - IpcAppConnectionString.WriteAccessToken(stream, tickCount64, Environment.ProcessId); - _AccessToken = Hashs.ByteArray.SHA256(stream); - Console.WriteLine($"Server,GetAccessToken:{_AccessToken.ToHexString()}, tickCount64: {tickCount64}, pid: {Environment.ProcessId}"); + _AccessToken ??= GetAccessToken(); + return _AccessToken; } - return _AccessToken; } - /// - internal byte[] AccessToken => GetAccessToken(); - #region 同时实现释放模式和异步释放模式 https://learn.microsoft.com/zh-cn/dotnet/standard/garbage-collection/implementing-disposeasync#implement-both-dispose-and-async-dispose-patterns /// diff --git a/src/BD.Common8.Ipc/Models/IpcAppConnectionString.cs b/src/BD.Common8.Ipc/Models/IpcAppConnectionString.cs index 081953443..a4e3e0e65 100644 --- a/src/BD.Common8.Ipc/Models/IpcAppConnectionString.cs +++ b/src/BD.Common8.Ipc/Models/IpcAppConnectionString.cs @@ -28,49 +28,49 @@ public readonly struct IpcAppConnectionString /// public readonly int Int32Value { get; init; } - /// - public readonly long TickCount64 { get; init; } + ///// + //public readonly long TickCount64 { get; init; } - /// - public readonly int ProcessId { get; init; } + ///// + //public readonly int ProcessId { get; init; } - /// - /// 将连接字符串写入指定的流中 - /// - public void Write(Stream stream) - { - const byte formatType = 0; - stream.WriteByte(formatType); - var connectionStringType = Type; - stream.WriteByte((byte)connectionStringType); - stream.Write(BitConverter.GetBytes(TickCount64)); - stream.Write(BitConverter.GetBytes(ProcessId)); - switch (connectionStringType) - { - case IpcAppConnectionStringType.Https: - stream.Write(BitConverter.GetBytes(Int32Value)); - break; - case IpcAppConnectionStringType.UnixSocket: - stream.Write(Encoding.UTF8.GetBytes(StringValue.ThrowIsNull())); - break; - case IpcAppConnectionStringType.NamedPipe: - stream.Write(Encoding.UTF8.GetBytes(StringValue.ThrowIsNull())); - break; - default: - throw ThrowHelper.GetArgumentOutOfRangeException(connectionStringType); - } - } + ///// + ///// 将连接字符串写入指定的流中 + ///// + //public void Write(Stream stream) + //{ + // const byte formatType = 0; + // stream.WriteByte(formatType); + // var connectionStringType = Type; + // stream.WriteByte((byte)connectionStringType); + // stream.Write(BitConverter.GetBytes(TickCount64)); + // stream.Write(BitConverter.GetBytes(ProcessId)); + // switch (connectionStringType) + // { + // case IpcAppConnectionStringType.Https: + // stream.Write(BitConverter.GetBytes(Int32Value)); + // break; + // case IpcAppConnectionStringType.UnixSocket: + // stream.Write(Encoding.UTF8.GetBytes(StringValue.ThrowIsNull())); + // break; + // case IpcAppConnectionStringType.NamedPipe: + // stream.Write(Encoding.UTF8.GetBytes(StringValue.ThrowIsNull())); + // break; + // default: + // throw ThrowHelper.GetArgumentOutOfRangeException(connectionStringType); + // } + //} - /// - /// 将连接字符串转换为字节数组形式 - /// - public byte[] ToByteArray() - { - using var stream = new MemoryStream(); - Write(stream); - var buffer = stream.ToArray(); - return buffer; - } + ///// + ///// 将连接字符串转换为字节数组形式 + ///// + //public byte[] ToByteArray() + //{ + // using var stream = new MemoryStream(); + // Write(stream); + // var buffer = stream.ToArray(); + // return buffer; + //} /// /// 根据连接字符串类型的不同返回不同的字符串表达形式 @@ -83,71 +83,71 @@ public byte[] ToByteArray() _ => base.ToString(), }; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator IpcAppConnectionString?(byte[] buffer) - { - try - { - //var formatType = buffer[0]; - var connectionStringType = (IpcAppConnectionStringType)buffer[1]; - int startIndex = 2; - var tickCount64 = BitConverter.ToInt64(buffer, startIndex); - startIndex += sizeof(long); - var processId = BitConverter.ToInt32(buffer, startIndex); - startIndex += sizeof(int); - return connectionStringType switch - { - IpcAppConnectionStringType.Https => new() - { - Type = connectionStringType, - Int32Value = BitConverter.ToInt32(buffer, startIndex), - TickCount64 = tickCount64, - ProcessId = processId, - }, - IpcAppConnectionStringType.UnixSocket or IpcAppConnectionStringType.NamedPipe => new() - { - Type = connectionStringType, - StringValue = Encoding.UTF8.GetString(buffer, startIndex, buffer.Length - startIndex), - TickCount64 = tickCount64, - ProcessId = processId, - }, - _ => throw ThrowHelper.GetArgumentOutOfRangeException(connectionStringType), - }; - } - catch - { - return null; - } - } + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + //public static implicit operator IpcAppConnectionString?(byte[] buffer) + //{ + // try + // { + // //var formatType = buffer[0]; + // var connectionStringType = (IpcAppConnectionStringType)buffer[1]; + // int startIndex = 2; + // //var tickCount64 = BitConverter.ToInt64(buffer, startIndex); + // //startIndex += sizeof(long); + // //var processId = BitConverter.ToInt32(buffer, startIndex); + // //startIndex += sizeof(int); + // return connectionStringType switch + // { + // IpcAppConnectionStringType.Https => new() + // { + // Type = connectionStringType, + // Int32Value = BitConverter.ToInt32(buffer, startIndex), + // //TickCount64 = tickCount64, + // //ProcessId = processId, + // }, + // IpcAppConnectionStringType.UnixSocket or IpcAppConnectionStringType.NamedPipe => new() + // { + // Type = connectionStringType, + // StringValue = Encoding.UTF8.GetString(buffer, startIndex, buffer.Length - startIndex), + // //TickCount64 = tickCount64, + // //ProcessId = processId, + // }, + // _ => throw ThrowHelper.GetArgumentOutOfRangeException(connectionStringType), + // }; + // } + // catch + // { + // return null; + // } + //} - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator byte[](IpcAppConnectionString connectionString) - => connectionString.ToByteArray(); + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + //public static implicit operator byte[](IpcAppConnectionString connectionString) + // => connectionString.ToByteArray(); - /// - /// 写入身份验证令牌 - /// - /// - /// - /// - public static void WriteAccessToken(Stream stream, long tickCount64, int processId) - { - stream.Write(BitConverter.GetBytes(tickCount64)); - stream.Write(BitConverter.GetBytes(processId)); - stream.Write("-----"u8); - stream.WriteUtf16StrToUtf8OrCustom(Environment.NewLine); - stream.Position = 0; - } + ///// + ///// 写入身份验证令牌 + ///// + ///// + ///// + ///// + //public static void WriteAccessToken(Stream stream, long tickCount64, int processId) + //{ + // stream.Write(BitConverter.GetBytes(tickCount64)); + // stream.Write(BitConverter.GetBytes(processId)); + // stream.Write("-----"u8); + // stream.WriteUtf16StrToUtf8OrCustom(Environment.NewLine); + // stream.Position = 0; + //} - /// - /// 获取身份验证令牌 - /// - /// - public string GetAccessToken() - { - using var stream = new MemoryStream(); - WriteAccessToken(stream, TickCount64, ProcessId); - var accessToken = Hashs.String.SHA256(stream, false); - return $"{AuthenticationScheme} {accessToken}"; - } + ///// + ///// 获取身份验证令牌 + ///// + ///// + //public string GetAccessToken() + //{ + // using var stream = new MemoryStream(); + // WriteAccessToken(stream, TickCount64, ProcessId); + // var accessToken = Hashs.String.SHA256(stream, false); + // return $"{AuthenticationScheme} {accessToken}"; + //} } diff --git a/src/BD.Common8.SourceGenerator.Bcl/Templates/ConstantsByPathTemplate.cs b/src/BD.Common8.SourceGenerator.Bcl/Templates/ConstantsByPathTemplate.cs index 48c902018..7b4d99a16 100644 --- a/src/BD.Common8.SourceGenerator.Bcl/Templates/ConstantsByPathTemplate.cs +++ b/src/BD.Common8.SourceGenerator.Bcl/Templates/ConstantsByPathTemplate.cs @@ -66,6 +66,9 @@ protected override IEnumerable GetMultipleAtt /// public required ConstantsByPathGeneratedAttribute Attribute { get; init; } + + /// + public required int I { get; init; } } protected override SourceModel GetSourceModel(GetSourceModelArgs args) @@ -78,6 +81,7 @@ protected override SourceModel GetSourceModel(GetSourceModelArgs args) SourceModel model = new() { + I = args.i, Namespace = args.@namespace, TypeName = args.typeName, Attribute = args.attr, diff --git a/src/BD.Common8.SourceGenerator.Bcl/Templates/CopyPropertiesTemplate.cs b/src/BD.Common8.SourceGenerator.Bcl/Templates/CopyPropertiesTemplate.cs index 73b941144..02043032a 100644 --- a/src/BD.Common8.SourceGenerator.Bcl/Templates/CopyPropertiesTemplate.cs +++ b/src/BD.Common8.SourceGenerator.Bcl/Templates/CopyPropertiesTemplate.cs @@ -78,12 +78,16 @@ protected override IEnumerable GetMultipleAttr /// public required CopyPropertiesGeneratedAttribute Attribute { get; init; } + + /// + public required int I { get; init; } } protected override SourceModel GetSourceModel(GetSourceModelArgs args) { SourceModel model = new() { + I = args.i, Symbol = args.symbol, Namespace = args.@namespace, TypeName = args.typeName, diff --git a/src/BD.Common8.SourceGenerator.Bcl/Templates/SettingsPropertyTemplate.cs b/src/BD.Common8.SourceGenerator.Bcl/Templates/SettingsPropertyTemplate.cs index 74a19645d..e6f14a56e 100644 --- a/src/BD.Common8.SourceGenerator.Bcl/Templates/SettingsPropertyTemplate.cs +++ b/src/BD.Common8.SourceGenerator.Bcl/Templates/SettingsPropertyTemplate.cs @@ -66,12 +66,16 @@ protected override IEnumerable GetMultipleAttributes(ImmutableAr /// AttributeModel ISourceModel.Attribute => AttrModel; + + /// + public required int I { get; init; } } protected override SourceModel GetSourceModel(GetSourceModelArgs args) { SourceModel model = new() { + I = args.i, NamedTypeSymbol = args.symbol, Namespace = args.@namespace, TypeName = args.typeName, diff --git a/src/BD.Common8.SourceGenerator.Bcl/Templates/SingletonPartitionTemplate.cs b/src/BD.Common8.SourceGenerator.Bcl/Templates/SingletonPartitionTemplate.cs index 46b5d8f4d..ab3e26e71 100644 --- a/src/BD.Common8.SourceGenerator.Bcl/Templates/SingletonPartitionTemplate.cs +++ b/src/BD.Common8.SourceGenerator.Bcl/Templates/SingletonPartitionTemplate.cs @@ -61,12 +61,16 @@ protected override IEnumerable GetMultiple /// public required SingletonPartitionGeneratedAttribute Attribute { get; init; } + + /// + public required int I { get; init; } } protected override SourceModel GetSourceModel(GetSourceModelArgs args) { SourceModel model = new() { + I = args.i, Namespace = args.@namespace, TypeName = args.typeName, Attribute = args.attr, diff --git a/src/BD.Common8.SourceGenerator.Bcl/Templates/ViewModelWrapperTemplate.cs b/src/BD.Common8.SourceGenerator.Bcl/Templates/ViewModelWrapperTemplate.cs index ad2c6e643..0bbc42642 100644 --- a/src/BD.Common8.SourceGenerator.Bcl/Templates/ViewModelWrapperTemplate.cs +++ b/src/BD.Common8.SourceGenerator.Bcl/Templates/ViewModelWrapperTemplate.cs @@ -113,12 +113,16 @@ protected override IEnumerable GetMultipleAttributes(ImmutableAr /// AttributeModel ISourceModel.Attribute => AttrModel; + + /// + public required int I { get; init; } } protected override SourceModel GetSourceModel(GetSourceModelArgs args) { SourceModel model = new() { + I = args.i, NamedTypeSymbol = args.symbol, Namespace = args.@namespace, TypeName = args.typeName, diff --git a/src/BD.Common8.SourceGenerator.Ipc.Client/Templates/Abstractions/IpcTemplateBase.cs b/src/BD.Common8.SourceGenerator.Ipc.Client/Templates/Abstractions/IpcTemplateBase.cs index e0ae9a4a7..abbb57dac 100644 --- a/src/BD.Common8.SourceGenerator.Ipc.Client/Templates/Abstractions/IpcTemplateBase.cs +++ b/src/BD.Common8.SourceGenerator.Ipc.Client/Templates/Abstractions/IpcTemplateBase.cs @@ -92,6 +92,9 @@ protected override IEnumerable GetMultipleAttribut /// public required ServiceContractImplAttribute Attribute { get; init; } + + /// + public required int I { get; init; } } /// @@ -113,6 +116,7 @@ protected sealed override SourceModel GetSourceModel(GetSourceModelArgs args) SourceModel model = new() { + I = args.i, NamedTypeSymbol = args.symbol, Namespace = args.@namespace, TypeName = args.typeName, diff --git a/src/BD.Common8.SourceGenerator.ResX/Templates/BinaryResourceTemplate.cs b/src/BD.Common8.SourceGenerator.ResX/Templates/BinaryResourceTemplate.cs index 109b22c44..73b0467dc 100644 --- a/src/BD.Common8.SourceGenerator.ResX/Templates/BinaryResourceTemplate.cs +++ b/src/BD.Common8.SourceGenerator.ResX/Templates/BinaryResourceTemplate.cs @@ -155,6 +155,9 @@ static void WritePropertyName(BinaryResourceFileInfo fileInfo, Stream stream) /// 生成的类型是否为 /// public required bool IsPublic { get; init; } + + /// + public required int I { get; init; } } protected override SourceModel GetSourceModel(GetSourceModelArgs args) @@ -173,6 +176,7 @@ protected override SourceModel GetSourceModel(GetSourceModelArgs args) SourceModel model = new() { + I = args.i, NamedTypeSymbol = args.symbol, Attribute = args.attr, FileInfos = queryFilePaths.ToArray(), diff --git a/src/BD.Common8.SourceGenerator.ResX/Templates/DesignerTemplate.cs b/src/BD.Common8.SourceGenerator.ResX/Templates/DesignerTemplate.cs index bf0d99c7a..4c9e57716 100644 --- a/src/BD.Common8.SourceGenerator.ResX/Templates/DesignerTemplate.cs +++ b/src/BD.Common8.SourceGenerator.ResX/Templates/DesignerTemplate.cs @@ -77,6 +77,9 @@ protected override IEnumerable GetMultipleAttributes /// 生成器是否使用 StringResourceManager 的代码模板 /// public required bool IsSRM { get; init; } + + /// + public required int I { get; init; } } protected override SourceModel GetSourceModel(GetSourceModelArgs args) @@ -90,6 +93,7 @@ protected override SourceModel GetSourceModel(GetSourceModelArgs args) SourceModel model = new() { + I = args.i, NamedTypeSymbol = args.symbol, Attribute = args.attr, Path = path, diff --git a/src/BD.Common8.SourceGenerator.Shared/Templates/Abstractions/TemplateBase.cs b/src/BD.Common8.SourceGenerator.Shared/Templates/Abstractions/TemplateBase.cs index b0a0bcd59..f2bd6e205 100644 --- a/src/BD.Common8.SourceGenerator.Shared/Templates/Abstractions/TemplateBase.cs +++ b/src/BD.Common8.SourceGenerator.Shared/Templates/Abstractions/TemplateBase.cs @@ -332,6 +332,8 @@ public interface ISourceModel /// 生成特性模型 /// TGeneratedAttribute Attribute { get; } + + int I { get; } } /// @@ -398,6 +400,8 @@ protected record struct GetSourceModelArgs /// 调用 的返回值 /// public TGeneratedAttribute attr; + + public int i; } #pragma warning restore SA1604 // Element documentation should have summary @@ -456,19 +460,14 @@ protected virtual void Execute(SourceProductionContext spc, GeneratorAttributeSy @namespace = @namespace, typeName = typeName, attr = attr, + i = i, }); if (IgnoreExecute || model is null) return; ExecuteCore(spc, model); - if (i >= 1) - { + if (!AllowMultiple && i >= 1) AllowMultiple = true; - i = -1; - } - else if (i >= 0) - { - i++; - } + i++; } } #pragma warning disable CS0168 // 声明了变量,但从未使用过 @@ -559,7 +558,7 @@ protected virtual void ExecuteCore(SourceProductionContext spc, TSourceModel m) ConsoleWriteSourceText(sourceTextString); #endif } - var hintName = $"{(string.IsNullOrEmpty(m.Namespace) ? "global_namespace" : m.Namespace)}.{m.TypeName}.{FileId}{(AllowMultiple ? "." + GetRandomFieldName() : "")}.g.cs"; + var hintName = $"{(string.IsNullOrEmpty(m.Namespace) ? "global_namespace" : m.Namespace)}.{m.TypeName}.{FileId}{(AllowMultiple ? "." + m.I : "")}.g.cs"; spc.AddSource(hintName, sourceText); }