diff --git a/JiShe.CollectBus.sln b/JiShe.CollectBus.sln
index 2e5826f..0232b6d 100644
--- a/JiShe.CollectBus.sln
+++ b/JiShe.CollectBus.sln
@@ -62,7 +62,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "0.Docs", "0.Docs", "{D8346C
readme.md = readme.md
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.SourceExtend", "shared\JiShe.CollectBus.SourceExtend\JiShe.CollectBus.SourceExtend.csproj", "{A34A4EA6-AEB0-4199-8E3A-6F042DBB51D9}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.IncrementalGenerator", "shared\JiShe.CollectBus.IncrementalGenerator\JiShe.CollectBus.IncrementalGenerator.csproj", "{828D20BC-454E-0467-B29D-429B25F1E0CA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -150,10 +150,10 @@ Global
{75B7D419-C261-577D-58D6-AA3ACED9129F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{75B7D419-C261-577D-58D6-AA3ACED9129F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{75B7D419-C261-577D-58D6-AA3ACED9129F}.Release|Any CPU.Build.0 = Release|Any CPU
- {A34A4EA6-AEB0-4199-8E3A-6F042DBB51D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A34A4EA6-AEB0-4199-8E3A-6F042DBB51D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A34A4EA6-AEB0-4199-8E3A-6F042DBB51D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A34A4EA6-AEB0-4199-8E3A-6F042DBB51D9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {828D20BC-454E-0467-B29D-429B25F1E0CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {828D20BC-454E-0467-B29D-429B25F1E0CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {828D20BC-454E-0467-B29D-429B25F1E0CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {828D20BC-454E-0467-B29D-429B25F1E0CA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -179,7 +179,7 @@ Global
{8A61DF78-069B-40B5-8811-614E2960443E} = {3C3F9DB2-EC97-4464-B49F-BF1A0C2B46DC}
{E27377CC-E2D3-4237-060F-96EA214D3129} = {3C3F9DB2-EC97-4464-B49F-BF1A0C2B46DC}
{75B7D419-C261-577D-58D6-AA3ACED9129F} = {3C3F9DB2-EC97-4464-B49F-BF1A0C2B46DC}
- {A34A4EA6-AEB0-4199-8E3A-6F042DBB51D9} = {EBF7C01F-9B4F-48E6-8418-2CBFDA51EB0B}
+ {828D20BC-454E-0467-B29D-429B25F1E0CA} = {EBF7C01F-9B4F-48E6-8418-2CBFDA51EB0B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4324B3B4-B60B-4E3C-91D8-59576B4E26DD}
diff --git a/modules/JiShe.CollectBus.IoTDB/JiShe.CollectBus.IoTDB.csproj b/modules/JiShe.CollectBus.IoTDB/JiShe.CollectBus.IoTDB.csproj
index afd5a8a..0e8250e 100644
--- a/modules/JiShe.CollectBus.IoTDB/JiShe.CollectBus.IoTDB.csproj
+++ b/modules/JiShe.CollectBus.IoTDB/JiShe.CollectBus.IoTDB.csproj
@@ -3,7 +3,7 @@
net8.0
enable
- enable
+ enable
@@ -11,6 +11,5 @@
-
diff --git a/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs b/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs
index d48f766..3350172 100644
--- a/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs
+++ b/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs
@@ -1,12 +1,6 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using JiShe.CollectBus.Common.Attributes;
+using JiShe.CollectBus.Common;
using JiShe.CollectBus.IoTDB.Attribute;
using JiShe.CollectBus.IoTDB.Enums;
-using JiShe.CollectBus.IoTDB.Provider;
namespace JiShe.CollectBus.IoTDB.Model
{
diff --git a/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs b/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs
index 9b3609c..2a3273b 100644
--- a/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs
+++ b/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs
@@ -1,11 +1,6 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using JiShe.CollectBus.Common;
using JiShe.CollectBus.IoTDB.Attribute;
-using JiShe.CollectBus.IoTDB.Enums;
-using JiShe.CollectBus.IoTDB.Provider;
+using JiShe.CollectBus.IoTDB.Enums;
namespace JiShe.CollectBus.IoTDB.Model
{
@@ -13,6 +8,7 @@ namespace JiShe.CollectBus.IoTDB.Model
/// Tree模型单项数据实体
///
[EntityType(EntityTypeEnum.TreeModel)]
+ [GenerateAccessors]
public class TreeModelSingleMeasuringEntity : IoTEntity
{
///
diff --git a/services/JiShe.CollectBus.Application/JiShe.CollectBus.Application.csproj b/services/JiShe.CollectBus.Application/JiShe.CollectBus.Application.csproj
index aefe5e4..b43d994 100644
--- a/services/JiShe.CollectBus.Application/JiShe.CollectBus.Application.csproj
+++ b/services/JiShe.CollectBus.Application/JiShe.CollectBus.Application.csproj
@@ -30,6 +30,8 @@
+
+
diff --git a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
index 31a3494..6392b83 100644
--- a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
+++ b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
@@ -66,6 +66,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
IssuedMessageHexString = "messageHexString",
Timestamps = testTime// DateTimeOffset.UtcNow.ToUnixTimeNanoseconds()//testTime.GetDateTimeOffset().ToUnixTimeNanoseconds(),
};
+
await _iotDBProvider.InsertAsync(meter);
}
diff --git a/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs b/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs
index 7fe7ebc..a9ddc93 100644
--- a/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs
+++ b/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs
@@ -1,10 +1,12 @@
-using JiShe.CollectBus.IoTDB.Attribute;
+using JiShe.CollectBus.Common;
+using JiShe.CollectBus.IoTDB.Attribute;
using JiShe.CollectBus.IoTDB.Enums;
-using JiShe.CollectBus.IoTDB.Model;
+using JiShe.CollectBus.IoTDB.Model;
namespace JiShe.CollectBus.Ammeters
{
[EntityType(EntityTypeEnum.TreeModel)]
+ [GenerateAccessors]
public class ElectricityMeterTreeModel : IoTEntity
{
[ATTRIBUTEColumn]
diff --git a/services/JiShe.CollectBus.Domain/IotSystems/MeterReadingRecords/MeterReadingTelemetryPacketInfo.cs b/services/JiShe.CollectBus.Domain/IotSystems/MeterReadingRecords/MeterReadingTelemetryPacketInfo.cs
index 1b5c954..552084f 100644
--- a/services/JiShe.CollectBus.Domain/IotSystems/MeterReadingRecords/MeterReadingTelemetryPacketInfo.cs
+++ b/services/JiShe.CollectBus.Domain/IotSystems/MeterReadingRecords/MeterReadingTelemetryPacketInfo.cs
@@ -1,16 +1,8 @@
-using JiShe.CollectBus.Common.Encrypt;
-using JiShe.CollectBus.Common.Enums;
-using JiShe.CollectBus.Common.Models;
+using JiShe.CollectBus.Common;
using JiShe.CollectBus.IoTDB.Attribute;
using JiShe.CollectBus.IoTDB.Enums;
using JiShe.CollectBus.IoTDB.Model;
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Volo.Abp.Domain.Entities;
-using Volo.Abp.Domain.Entities.Auditing;
namespace JiShe.CollectBus.IotSystems.MeterReadingRecords
{
@@ -18,6 +10,7 @@ namespace JiShe.CollectBus.IotSystems.MeterReadingRecords
/// 抄读任务数据
///
[EntityType(EntityTypeEnum.TableModel)]
+ [GenerateAccessors]
public class MeterReadingTelemetryPacketInfo : IoTEntity
{
///
diff --git a/services/JiShe.CollectBus.Domain/JiShe.CollectBus.Domain.csproj b/services/JiShe.CollectBus.Domain/JiShe.CollectBus.Domain.csproj
index 1914993..44b8a3e 100644
--- a/services/JiShe.CollectBus.Domain/JiShe.CollectBus.Domain.csproj
+++ b/services/JiShe.CollectBus.Domain/JiShe.CollectBus.Domain.csproj
@@ -25,7 +25,7 @@
-
+
diff --git a/shared/JiShe.CollectBus.SourceExtend/GenerateAccessorsAttribute.cs b/shared/JiShe.CollectBus.Common/Attributes/GenerateAccessorsAttribute.cs
similarity index 59%
rename from shared/JiShe.CollectBus.SourceExtend/GenerateAccessorsAttribute.cs
rename to shared/JiShe.CollectBus.Common/Attributes/GenerateAccessorsAttribute.cs
index b739a54..4912185 100644
--- a/shared/JiShe.CollectBus.SourceExtend/GenerateAccessorsAttribute.cs
+++ b/shared/JiShe.CollectBus.Common/Attributes/GenerateAccessorsAttribute.cs
@@ -1,10 +1,6 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-namespace JiShe.CollectBus.SourceExtend
+namespace JiShe.CollectBus.Common
{
///
/// 标记需要生成源码的类
diff --git a/shared/JiShe.CollectBus.Common/JiShe.CollectBus.Common.csproj b/shared/JiShe.CollectBus.Common/JiShe.CollectBus.Common.csproj
index fdb6bfd..6cf0246 100644
--- a/shared/JiShe.CollectBus.Common/JiShe.CollectBus.Common.csproj
+++ b/shared/JiShe.CollectBus.Common/JiShe.CollectBus.Common.csproj
@@ -25,8 +25,7 @@
-
-
+
diff --git a/shared/JiShe.CollectBus.Common/Models/ServerApplicationOptions.cs b/shared/JiShe.CollectBus.Common/Models/ServerApplicationOptions.cs
index 2eb92c5..525b5a2 100644
--- a/shared/JiShe.CollectBus.Common/Models/ServerApplicationOptions.cs
+++ b/shared/JiShe.CollectBus.Common/Models/ServerApplicationOptions.cs
@@ -8,12 +8,12 @@
///
/// 服务器标识
///
- public required string ServerTagName { get; set; }
+ public string ServerTagName { get; set; }
///
/// 系统类型
///
- public required string SystemType { get; set; }
+ public string SystemType { get; set; }
///
/// 首次采集时间
@@ -23,31 +23,31 @@
///
/// 自动验证时间
///
- public required string AutomaticVerificationTime { get; set; }
+ public string AutomaticVerificationTime { get; set; }
///
/// 自动获取终端版时间
///
- public required string AutomaticTerminalVersionTime { get; set; }
+ public string AutomaticTerminalVersionTime { get; set; }
///
/// 自动获取远程通信模块(SIM)版本时间
///
- public required string AutomaticTelematicsModuleTime { get; set; }
+ public string AutomaticTelematicsModuleTime { get; set; }
///
/// 日冻结抄读时间
///
- public required string AutomaticDayFreezeTime { get; set; }
+ public string AutomaticDayFreezeTime { get; set; }
///
/// 月冻结抄读时间
///
- public required string AutomaticMonthFreezeTime { get; set; }
+ public string AutomaticMonthFreezeTime { get; set; }
///
/// 默认协议插件
///
- public required string DefaultProtocolPlugin { get; set; }
+ public string DefaultProtocolPlugin { get; set; }
}
}
diff --git a/shared/JiShe.CollectBus.IncrementalGenerator/ComplexTypeSourceGenerator.cs b/shared/JiShe.CollectBus.IncrementalGenerator/ComplexTypeSourceGenerator.cs
new file mode 100644
index 0000000..1530a2c
--- /dev/null
+++ b/shared/JiShe.CollectBus.IncrementalGenerator/ComplexTypeSourceGenerator.cs
@@ -0,0 +1,223 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Text;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace JiShe.CollectBus.IncrementalGenerator
+{
+ ///
+ /// 复杂类型源生成器
+ ///
+ [Generator(LanguageNames.CSharp)]
+ public class ComplexTypeSourceGenerator : IIncrementalGenerator
+ {
+ private const string AttributeFullName = "JiShe.CollectBus.Common.GenerateAccessorsAttribute";
+
+ public void Initialize(IncrementalGeneratorInitializationContext context)
+ {
+
+ Debugger.Launch();
+
+ context.RegisterPostInitializationOutput(ctx =>
+ {
+ ctx.AddSource("DebugInit.g.cs", "// Generator initialized");
+ });
+
+ // 步骤1:筛选带有 [GenerateAccessors] 的类
+ var classDeclarations = context.SyntaxProvider
+ .CreateSyntaxProvider(
+ predicate: static (s, _) => IsClassWithAttribute(s),
+ transform: static (ctx, _) => GetClassDeclaration(ctx))
+ .Where(static c => c is not null);
+
+ // 步骤2:合并编译信息
+ var compilationAndClasses = context.CompilationProvider.Combine(classDeclarations.Collect());
+
+ context.RegisterSourceOutput(compilationAndClasses, (spc, source) =>
+ GenerateCode(source.Left, source.Right!, spc));
+ }
+
+ private static bool IsClassWithAttribute(SyntaxNode node) => node is ClassDeclarationSyntax cds && cds.AttributeLists.Count > 0;
+
+ //private static ClassDeclarationSyntax? GetClassDeclaration(GeneratorSyntaxContext context)
+ //{
+ // var classDecl = (ClassDeclarationSyntax)context.Node;
+ // foreach (var attributeList in classDecl.AttributeLists)
+ // {
+ // foreach (var attribute in attributeList.Attributes)
+ // {
+ // var symbol = context.SemanticModel.GetSymbolInfo(attribute).Symbol;
+ // if (symbol is IMethodSymbol ctor)
+ // {
+ // string sdd = ctor.ContainingType.Name;
+ // var attributeType = context.SemanticModel.Compilation.GetTypeByMetadataName(AttributeFullName);
+ // if (ctor.ContainingType?.OriginalDefinition?.Equals(attributeType, SymbolEqualityComparer.Default) == true)
+ // {
+ // return classDecl;
+ // }
+ // }
+
+ // }
+ // }
+ // return null;
+ //}
+
+ private static ClassDeclarationSyntax? GetClassDeclaration(GeneratorSyntaxContext context)
+ {
+ var classDecl = (ClassDeclarationSyntax)context.Node;
+ var attributeType = context.SemanticModel.Compilation.GetTypeByMetadataName(AttributeFullName);
+
+ foreach (var attribute in classDecl.AttributeLists.SelectMany(al => al.Attributes))
+ {
+ var symbol = context.SemanticModel.GetSymbolInfo(attribute).Symbol;
+ if (symbol is IMethodSymbol ctor &&
+ ctor.ContainingType?.OriginalDefinition?.Equals(attributeType, SymbolEqualityComparer.Default) == true)
+ {
+ return classDecl;
+ }
+ }
+ return null;
+ }
+
+ private static void GenerateCode(
+ Compilation compilation,
+ IEnumerable classes,
+ SourceProductionContext context)
+ {
+ var processedTypes = new HashSet(SymbolEqualityComparer.Default);
+
+
+ foreach (var classDecl in classes.Distinct())
+ {
+ var model = compilation.GetSemanticModel(classDecl.SyntaxTree);
+ var classSymbol = model.GetDeclaredSymbol(classDecl) as INamedTypeSymbol;
+
+ if (classSymbol == null || !processedTypes.Add(classSymbol)) continue;
+
+ context.ReportDiagnostic(Diagnostic.Create(
+ new DiagnosticDescriptor(
+ "PA001",
+ "Generated Accessors",
+ $"Generating accessors for {classSymbol.Name}",
+ "Performance",
+ DiagnosticSeverity.Info,
+ true),
+ Location.None));
+
+ context.ReportDiagnostic(Diagnostic.Create(
+ new DiagnosticDescriptor("PA002", "Class Found",
+ $"Processing class: {classSymbol.Name}", "Debug", DiagnosticSeverity.Warning, true),
+ Location.None));
+
+ var code = BuildAccessorsForType(classSymbol, compilation, processedTypes);
+ context.AddSource($"{classSymbol.Name}Extension.g.cs", SourceText.From(code, Encoding.UTF8));
+ }
+ }
+
+ private static string BuildAccessorsForType(
+ INamedTypeSymbol classSymbol,
+ Compilation compilation,
+ HashSet processedTypes)
+ {
+ var code = new StringBuilder();
+ code.AppendLine("// ");
+ code.AppendLine("#nullable enable");
+ code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
+ code.AppendLine();
+
+ code.AppendLine($"public static class {classSymbol.Name}Extension{GetGenericParams(classSymbol)}");
+ code.AppendLine("{");
+
+ foreach (var prop in classSymbol.GetMembers().OfType())
+ {
+ if (prop.IsIndexer) continue;
+
+ GeneratePropertyAccessors(prop, code, compilation, processedTypes);
+ }
+
+ code.AppendLine("}");
+ return code.ToString();
+ }
+
+ private static string GetGenericParams(INamedTypeSymbol symbol)
+ => symbol.IsGenericType ? $"<{string.Join(", ", symbol.TypeParameters.Select(t => t.Name))}>" : "";
+
+ private static void GeneratePropertyAccessors(
+ IPropertySymbol prop,
+ StringBuilder code,
+ Compilation compilation,
+ HashSet processedTypes)
+ {
+ // 关键修复点1:安全类型转换
+ if (prop.Type is not ITypeSymbol propType) return;
+
+ code.AppendLine($" // Processing property: {prop.Name}");
+
+ // 处理元组类型
+ if (propType is INamedTypeSymbol { IsTupleType: true } tupleType)
+ {
+ GenerateTupleAccessors(prop, tupleType, code);
+ }
+ else if (propType is INamedTypeSymbol namedType)
+ {
+ GenerateStandardAccessors(prop, namedType, code);
+ ProcessNestedType(namedType, compilation, processedTypes);
+ }
+ }
+
+ private static void GenerateTupleAccessors(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code)
+ {
+ var elements = tupleType.TupleElements;
+ var parentType = prop.ContainingType.ToDisplayString();
+
+ for (int i = 0; i < elements.Length; i++)
+ {
+ var element = elements[i];
+ if (element.Type is not ITypeSymbol elementType) continue;
+
+ var elementName = element.CorrespondingTupleField?.Name ?? $"Item{i + 1}";
+ code.AppendLine($" public static {elementType.ToDisplayString()} Get{prop.Name}_{elementName}({parentType} obj) => obj.{prop.Name}.{elementName};");
+
+ if (prop.SetMethod != null)
+ {
+ var assignments = elements.Select((e, idx) =>
+ idx == i ? "value" : $"obj.{prop.Name}.{e.Name}");
+ code.AppendLine($" public static void Set{prop.Name}_{elementName}({parentType} obj, {elementType.ToDisplayString()} value) => obj.{prop.Name} = ({string.Join(", ", assignments)});");
+ }
+ }
+ }
+
+ private static void GenerateStandardAccessors(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code)
+ {
+ var parentType = prop.ContainingType.ToDisplayString();
+ code.AppendLine($" public static {propType.ToDisplayString()} Get{prop.Name}({parentType} obj) => obj.{prop.Name};");
+
+ if (prop.SetMethod != null)
+ {
+ code.AppendLine($" public static void Set{prop.Name}({parentType} obj, {propType.ToDisplayString()} value) => obj.{prop.Name} = value;");
+ }
+ }
+
+ private static void ProcessNestedType(ITypeSymbol typeSymbol, Compilation compilation, HashSet processedTypes)
+ {
+ if (typeSymbol is not INamedTypeSymbol namedType) return;
+ if (!ShouldProcessNestedType(namedType)) return;
+ if (!processedTypes.Add(namedType)) return;
+
+ var code = BuildAccessorsForType(namedType, compilation, processedTypes);
+ }
+
+ private static bool ShouldProcessNestedType(INamedTypeSymbol symbol)
+ {
+ return symbol.DeclaredAccessibility == Accessibility.Public &&
+ !symbol.IsTupleType &&
+ !symbol.IsAnonymousType &&
+ !symbol.IsImplicitlyDeclared &&
+ !symbol.Name.StartsWith("<");
+ }
+ }
+}
\ No newline at end of file
diff --git a/shared/JiShe.CollectBus.IncrementalGenerator/JiShe.CollectBus.IncrementalGenerator.csproj b/shared/JiShe.CollectBus.IncrementalGenerator/JiShe.CollectBus.IncrementalGenerator.csproj
new file mode 100644
index 0000000..c36ce2b
--- /dev/null
+++ b/shared/JiShe.CollectBus.IncrementalGenerator/JiShe.CollectBus.IncrementalGenerator.csproj
@@ -0,0 +1,14 @@
+
+
+
+ enable
+ netstandard2.0
+
+ true
+ latest
+
+
+
+
+
+
diff --git a/shared/JiShe.CollectBus.SourceExtend/ComplexTypeSourceGenerator.cs b/shared/JiShe.CollectBus.SourceExtend/ComplexTypeSourceGenerator.cs
deleted file mode 100644
index 352cd4a..0000000
--- a/shared/JiShe.CollectBus.SourceExtend/ComplexTypeSourceGenerator.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Microsoft.CodeAnalysis.Text;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace JiShe.CollectBus.SourceExtend
-{
- ///
- /// 复杂类型源生成器
- ///
- [Generator]
- public sealed class PropertyAccessorGenerator : IIncrementalGenerator
- {
- private const string AttributeName = "GenerateAccessors";
-
- public void Initialize(IncrementalGeneratorInitializationContext context)
- {
- // 步骤1:筛选带有 [GenerateAccessors] 的类
- var classDeclarations = context.SyntaxProvider
- .CreateSyntaxProvider(
- predicate: static (s, _) => IsClassWithAttribute(s),
- transform: static (ctx, _) => GetClassDeclaration(ctx))
- .Where(static c => c is not null);
-
- // 步骤2:编译符号并生成代码
- var compilationAndClasses = context.CompilationProvider.Combine(classDeclarations.Collect());
-
- context.RegisterSourceOutput(compilationAndClasses, (spc, source) =>
- GenerateCode(source.Left, source.Right!, spc));
- }
-
- private static bool IsClassWithAttribute(SyntaxNode node)
- {
- return node is ClassDeclarationSyntax { AttributeLists.Count: > 0 };
- }
-
- private static ClassDeclarationSyntax? GetClassDeclaration(GeneratorSyntaxContext context)
- {
- var classDecl = (ClassDeclarationSyntax)context.Node;
- foreach (var attributeList in classDecl.AttributeLists)
- {
- foreach (var attribute in attributeList.Attributes)
- {
- var symbol = context.SemanticModel.GetSymbolInfo(attribute).Symbol;
- if (symbol?.ContainingType.ToDisplayString() == $"{nameof(PropertyAccessorGenerator)}.{AttributeName}")
- {
- return classDecl;
- }
- }
- }
- return null;
- }
-
- private static void GenerateCode(
- Compilation compilation,
- IEnumerable classes,
- SourceProductionContext context)
- {
- var processedTypes = new HashSet(SymbolEqualityComparer.Default);
-
- foreach (var classDecl in classes.Distinct())
- {
- var model = compilation.GetSemanticModel(classDecl.SyntaxTree);
- var classSymbol = model.GetDeclaredSymbol(classDecl)!;
-
- if (!processedTypes.Add(classSymbol)) continue;
-
- var code = BuildAccessorsForType(classSymbol, compilation, processedTypes);
- context.AddSource($"{classSymbol.Name}Accessors.g.cs", code);
- }
- }
-
- private static string BuildAccessorsForType(
- INamedTypeSymbol classSymbol,
- Compilation compilation,
- HashSet processedTypes)
- {
- var code = new StringBuilder();
- code.AppendLine("// ");
- code.AppendLine("#nullable enable");
- code.AppendLine();
- code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
- code.AppendLine();
-
- // 处理泛型参数
- var genericParams = classSymbol.IsGenericType
- ? $"<{string.Join(", ", classSymbol.TypeParameters.Select(t => t.Name))}>"
- : "";
-
- code.AppendLine($"public static class {classSymbol.Name}Accessors{genericParams}");
- code.AppendLine("{");
-
- foreach (var prop in classSymbol.GetMembers().OfType())
- {
- if (prop.IsIndexer) continue;
-
- GeneratePropertyAccessors(prop, code, compilation, processedTypes);
- }
-
- code.AppendLine("}");
- return code.ToString();
- }
-
- private static void GeneratePropertyAccessors(
- IPropertySymbol prop,
- StringBuilder code,
- Compilation compilation,
- HashSet processedTypes)
- {
- var propType = prop.Type;
- var parentType = prop.ContainingType.ToDisplayString();
-
- // 处理元组类型
- if (propType.IsTupleType && propType is INamedTypeSymbol tupleType)
- {
- GenerateTupleAccessors(prop, tupleType, code);
- }
- else if (propType is INamedTypeSymbol namedType)
- {
- GenerateStandardAccessors(prop, namedType, code);
- ProcessNestedType(namedType, compilation, processedTypes);
- }
- }
-
- private static void GenerateTupleAccessors(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code)
- {
- var elements = tupleType.TupleElements;
- var parentType = prop.ContainingType.ToDisplayString();
-
- for (int i = 0; i < elements.Length; i++)
- {
- var element = elements[i];
- var elementType = element.Type.ToDisplayString();
- var elementName = element.CorrespondingTupleField?.Name ?? $"Item{i + 1}";
-
- code.AppendLine($" public static {elementType} Get{prop.Name}_{elementName}({parentType} obj)");
- code.AppendLine($" => obj.{prop.Name}.{elementName};");
-
- if (prop.SetMethod != null)
- {
- var assignments = elements.Select((e, idx) =>
- idx == i ? "value" : $"obj.{prop.Name}.{e.Name}");
-
- code.AppendLine($" public static void Set{prop.Name}_{elementName}({parentType} obj, {elementType} value)");
- code.AppendLine($" => obj.{prop.Name} = ({string.Join(", ", assignments)});");
- }
- }
- }
-
- private static void GenerateStandardAccessors(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code)
- {
- var typeName = propType.ToDisplayString();
- var parentType = prop.ContainingType.ToDisplayString();
-
- code.AppendLine($" public static {typeName} Get{prop.Name}({parentType} obj)");
- code.AppendLine($" => obj.{prop.Name};");
-
- if (prop.SetMethod != null)
- {
- code.AppendLine($" public static void Set{prop.Name}({parentType} obj, {typeName} value)");
- code.AppendLine($" => obj.{prop.Name} = value;");
- }
- }
-
- private static void ProcessNestedType(INamedTypeSymbol typeSymbol, Compilation compilation, HashSet processedTypes)
- {
- if (ShouldGenerateForType(typeSymbol) && processedTypes.Add(typeSymbol))
- {
- var code = BuildAccessorsForType(typeSymbol, compilation, processedTypes);
- // 注意:实际项目中需要通过 SourceProductionContext 添加源代码
- }
- }
-
- private static bool ShouldGenerateForType(INamedTypeSymbol typeSymbol)
- {
- return !typeSymbol.IsTupleType &&
- !typeSymbol.IsAnonymousType &&
- !typeSymbol.IsNativeIntegerType &&
- typeSymbol.DeclaredAccessibility == Accessibility.Public &&
- !typeSymbol.Name.StartsWith("<");
- }
- }
-}
\ No newline at end of file
diff --git a/shared/JiShe.CollectBus.SourceExtend/JiShe.CollectBus.SourceExtend.csproj b/shared/JiShe.CollectBus.SourceExtend/JiShe.CollectBus.SourceExtend.csproj
deleted file mode 100644
index a06bde8..0000000
--- a/shared/JiShe.CollectBus.SourceExtend/JiShe.CollectBus.SourceExtend.csproj
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
- netstandard2.1
- 12.0
- enable
- true
-
-
-
-
-
diff --git a/web/JiShe.CollectBus.Host/JiShe.CollectBus.Host.csproj b/web/JiShe.CollectBus.Host/JiShe.CollectBus.Host.csproj
index 4ebd67d..5501841 100644
--- a/web/JiShe.CollectBus.Host/JiShe.CollectBus.Host.csproj
+++ b/web/JiShe.CollectBus.Host/JiShe.CollectBus.Host.csproj
@@ -5,7 +5,7 @@
enable
enable
True
-
+
@@ -55,9 +55,9 @@
-
-
-
+
+
+