From 53e6bb252ab74375010fbe6877ce5ced5590e47d Mon Sep 17 00:00:00 2001
From: ChenYi <296215406@outlook.com>
Date: Tue, 6 May 2025 23:46:12 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D15=E5=88=86=E9=92=9F=E4=BB=BB?=
=?UTF-8?q?=E5=8A=A1Kafka=E4=B8=BB=E9=A2=98=E5=BC=82=E5=B8=B8=E7=9A=84?=
=?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=8C=E6=96=B0=E5=A2=9E=E5=A2=9E=E9=87=8F?=
=?UTF-8?q?=E6=BA=90=E7=A0=81=E5=B7=A5=E5=8E=82=E7=B1=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../ComplexTypeSourceAnalyzers.cs | 217 ++++++++++++++----
.../Samples/SampleAppService.cs | 5 +
.../BasicScheduledMeterReadingService.cs | 2 +-
...rsProvider.cs => ISourceEntityAccessor.cs} | 4 +-
4 files changed, 178 insertions(+), 50 deletions(-)
rename shared/JiShe.CollectBus.Analyzers.Shared/{ISourceAnalyzersProvider.cs => ISourceEntityAccessor.cs} (92%)
diff --git a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
index 20951e5..8ec5eb9 100644
--- a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
+++ b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
@@ -14,17 +14,14 @@ namespace JiShe.CollectBus.IncrementalGenerator
public class ComplexTypeSourceAnalyzers : IIncrementalGenerator
{
private const string AttributeFullName = "JiShe.CollectBus.Analyzers.Shared.SourceAnalyzersAttribute";
+ private const string SourceEntityAccessorFactoryNamespace = "JiShe.CollectBus.Analyzers.Shared";
public void Initialize(IncrementalGeneratorInitializationContext context)
{
//Debugger.Launch();
- context.RegisterPostInitializationOutput(ctx =>
- {
- ctx.AddSource("GeneratorInit.g.cs", "// Initialization Marker");
- });
- // 步骤1:筛选带有 [GenerateAccessors] 的类
+ // 步骤1:筛选带有 [SourceAnalyzers] 的类
var classDeclarations = context.SyntaxProvider
.CreateSyntaxProvider(
predicate: static (s, _) => IsClassWithAttribute(s),
@@ -35,12 +32,11 @@ namespace JiShe.CollectBus.IncrementalGenerator
var compilationAndClasses = context.CompilationProvider.Combine(classDeclarations.Collect());
context.RegisterSourceOutput(compilationAndClasses, (spc, source) =>
- GenerateCode(source.Left, source.Right!, spc));
+ 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;
@@ -76,18 +72,24 @@ namespace JiShe.CollectBus.IncrementalGenerator
}
}
+ ///
+ /// 生成代码
+ ///
+ ///
+ ///
+ ///
private static void GenerateCode(
Compilation compilation,
IEnumerable classes,
SourceProductionContext context)
{
var processedTypes = new HashSet(SymbolEqualityComparer.Default);
-
+
if (!classes.Any())
{
context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor("GEN002", "No Targets",
- "No classes with [GenerateAccessors] found", "Debug", DiagnosticSeverity.Warning, true),
+ new DiagnosticDescriptor("GEN002", "没有目标类",
+ "没有找到SourceAnalyzers标记的类", "Debug", DiagnosticSeverity.Warning, true),
Location.None));
}
@@ -99,46 +101,66 @@ namespace JiShe.CollectBus.IncrementalGenerator
if (classSymbol == null || !processedTypes.Add(classSymbol))
{
context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor("GEN003", "Invalid Symbol",
- $"Class symbol is null for {classDecl.Identifier.Text}", "Error", DiagnosticSeverity.Error, true),
+ new DiagnosticDescriptor("GEN003", "无效符号",
+ $"类名称为{classDecl.Identifier.Text} 符号为空", "Error", DiagnosticSeverity.Error, true),
Location.None));
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(
+ // "PA001",
+ // "Generated Accessors",
+ // $"Generating accessors for {classSymbol.Name}",
+ // "Performance",
+ // DiagnosticSeverity.Info,
+ // true),
+ //Location.None));
- // 新增:输出继承链信息
- context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor("HIERARCHY", "Class Hierarchy",
- $"Processing class: {classSymbol.Name}, BaseType: {classSymbol.BaseType?.Name}",
- "Debug", DiagnosticSeverity.Info, true),
- Location.None));
+ //// 新增:输出继承链信息
+ //context.ReportDiagnostic(Diagnostic.Create(
+ // new DiagnosticDescriptor("HIERARCHY", "Class Hierarchy",
+ // $"Processing class: {classSymbol.Name}, BaseType: {classSymbol.BaseType?.Name}",
+ // "Debug", DiagnosticSeverity.Info, true),
+ // Location.None));
- context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor("PA002", "Class Found",
- $"Processing class: {classSymbol.Name}", "Debug", DiagnosticSeverity.Warning, 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);
- System.Diagnostics.Debug.WriteLine($"Generated code for {classSymbol.Name}:\n{code}"); // 调试输出
+ //System.Diagnostics.Debug.WriteLine($"Generated code for {classSymbol.Name}:\n{code}"); // 调试输出
context.AddSource($"{classSymbol.Name}Extension.g.cs", code);
+
+
+ var code3 = BuildAccessorsForType2(classSymbol, compilation, processedTypes);
+ context.AddSource($"{classSymbol.Name}Accessor.g.cs", code3);
+
+ //code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
+ //if (classSymbol.ContainingNamespace.ToDisplayString() == "JiShe.CollectBus.IoTDB")
+ //{
+
+ //}
}
+
+ // 生成工厂注册代码
+ context.AddSource("SourceEntityAccessorFactory.g.cs", BuildFactoryCode());
}
+ ///
+ /// 构建类的属性访问器代码
+ ///
+ ///
+ ///
+ ///
+ ///
private static string BuildAccessorsForType(
- INamedTypeSymbol classSymbol,
- Compilation compilation,
- HashSet processedTypes)
+ INamedTypeSymbol classSymbol,
+ Compilation compilation,
+ HashSet processedTypes)
{
var code = new StringBuilder();
code.AppendLine("#pragma warning disable CS0419 // 禁用警告");
@@ -151,25 +173,67 @@ namespace JiShe.CollectBus.IncrementalGenerator
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);
- //}
-
foreach (var prop in GetAllPropertiesInHierarchy(classSymbol))
{
if (prop.IsIndexer) continue;
- GeneratePropertyAccessors(prop, code, compilation, processedTypes);
+ GeneratePropertyAccessorsForType(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 string BuildAccessorsForType2(
+ INamedTypeSymbol classSymbol,
+ Compilation compilation,
+ HashSet processedTypes)
+ {
+ var code = new StringBuilder();
+ code.AppendLine("#pragma warning disable CS0419 // 禁用警告");
+ code.AppendLine("// Generated code for " + classSymbol.Name);
+ code.AppendLine("// ");
+ code.AppendLine("#nullable enable");
+ code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
+ code.AppendLine();
+
+ code.AppendLine($"public sealed class {classSymbol.Name}Accessor : ISourceEntityAccessor<{classSymbol.Name}>");
+ code.AppendLine("{");
+
+ foreach (var prop in GetAllPropertiesInHierarchy(classSymbol))
+ {
+ if (prop.IsIndexer) continue;
+ GeneratePropertyAccessorsForType(prop, code, compilation, processedTypes);
+ }
+
+ code.AppendLine("}");
+
+ //var code3 = $@"
+ // public sealed class {classSymbol.Name}Accessor : ISourceEntityAccessor<{classSymbol.Name}>
+ // {{
+ // public object GetPropertyValue({classSymbol.Name} entity, string propName) => propName switch
+ // {{
+ // {GeneratePropertyCases(classSymbol)}
+ // _ => throw new ArgumentException(""无效属性名"")
+ // }};
+
+ // {GenerateTupleSupport(classSymbol)}
+ // }}";
+
+ return code.ToString();
+ }
+
+ ///
+ /// 获取泛型参数
+ ///
+ ///
+ ///
public static string GetGenericParams(INamedTypeSymbol symbol)
{
if (!symbol.IsGenericType) return "";
@@ -177,13 +241,20 @@ namespace JiShe.CollectBus.IncrementalGenerator
return $"<{string.Join(", ", parameters)}>";
}
- private static void GeneratePropertyAccessors(
+ ///
+ /// 生成属性访问器代码
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static void GeneratePropertyAccessorsForType(
IPropertySymbol prop,
StringBuilder code,
Compilation compilation,
HashSet processedTypes)
{
- // 关键修复点1:安全类型转换
+ // 安全类型转换
if (prop.Type is not ITypeSymbol propType) return;
code.AppendLine($" // Processing property: {prop.Name}");
@@ -200,6 +271,12 @@ namespace JiShe.CollectBus.IncrementalGenerator
}
}
+ ///
+ /// 处理元组类型
+ ///
+ ///
+ ///
+ ///
private static void GenerateTupleAccessors(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code)
{
var elements = tupleType.TupleElements;
@@ -222,6 +299,12 @@ namespace JiShe.CollectBus.IncrementalGenerator
}
}
+ ///
+ /// 生成标准属性的访问器
+ ///
+ ///
+ ///
+ ///
private static void GenerateStandardAccessors(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code)
{
var parentType = prop.ContainingType.ToDisplayString();
@@ -233,6 +316,13 @@ namespace JiShe.CollectBus.IncrementalGenerator
}
}
+
+ ///
+ /// 处理嵌套类型
+ ///
+ ///
+ ///
+ ///
private static void ProcessNestedType(ITypeSymbol typeSymbol, Compilation compilation, HashSet processedTypes)
{
if (typeSymbol is not INamedTypeSymbol namedType) return;
@@ -242,6 +332,11 @@ namespace JiShe.CollectBus.IncrementalGenerator
var code = BuildAccessorsForType(namedType, compilation, processedTypes);
}
+ ///
+ /// 处理嵌套类型
+ ///
+ ///
+ ///
private static bool ShouldProcessNestedType(INamedTypeSymbol symbol)
{
return symbol.DeclaredAccessibility == Accessibility.Public &&
@@ -250,5 +345,33 @@ namespace JiShe.CollectBus.IncrementalGenerator
!symbol.IsImplicitlyDeclared &&
!symbol.Name.StartsWith("<");
}
+
+ ///
+ /// 生成扩展类工厂代码
+ ///
+ ///
+ private static string BuildFactoryCode()
+ {
+ return """
+ using System;
+ using System.Collections.Concurrent;
+ namespace JiShe.CollectBus.Analyzers.Shared;
+ public static class SourceEntityAccessorFactory
+ {
+ private static readonly ConcurrentDictionary _accessors = new();
+
+ public static ISourceEntityAccessor GetAccessor()
+ {
+ if (!_accessors.TryGetValue(typeof(T), out var accessor))
+ {
+ accessor = Activator.CreateInstance(
+ Type.GetType($"{typeof(T).Namespace}.{typeof(T).Name}Accessor")!)!;
+ _accessors.TryAdd(typeof(T), accessor);
+ }
+ return (ISourceEntityAccessor)accessor!;
+ }
+ }
+ """;
+ }
}
}
\ No newline at end of file
diff --git a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
index ea2415e..79f0244 100644
--- a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
+++ b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
@@ -53,6 +53,10 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
[HttpGet]
public async Task UseSessionPool(long testTime)
{
+ var dataTime = DateTime.Now;
+
+ List values = new List() { $"{dataTime:yy}", $"{dataTime:MM}", $"{dataTime:dd}", $"{dataTime:HH}", $"{dataTime:mm}", };
+
ElectricityMeterTreeModel meter = new ElectricityMeterTreeModel()
{
@@ -67,6 +71,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
Timestamps = testTime// DateTimeOffset.UtcNow.ToUnixTimeNanoseconds()//testTime.GetDateTimeOffset().ToUnixTimeNanoseconds(),
};
//ElectricityMeterTreeModelExtension.GetCurrent()
+ //SourceEntityAccessorFactory.SetCurrent(meter);
await _iotDBProvider.InsertAsync(meter);
}
diff --git a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
index 2104d28..47b8a99 100644
--- a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
+++ b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
@@ -262,7 +262,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
//_logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}");
return;
}
- _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, Tuple.Create(ProtocolConst.AmmeterSubscriberWorkerAutoValveControlIssuedEventName, tempTask));
+ _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, Tuple.Create(ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName, tempTask));
});
}
else if (meteryType == MeterTypeEnum.WaterMeter.ToString())
diff --git a/shared/JiShe.CollectBus.Analyzers.Shared/ISourceAnalyzersProvider.cs b/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
similarity index 92%
rename from shared/JiShe.CollectBus.Analyzers.Shared/ISourceAnalyzersProvider.cs
rename to shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
index 905f0ef..3395239 100644
--- a/shared/JiShe.CollectBus.Analyzers.Shared/ISourceAnalyzersProvider.cs
+++ b/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
@@ -2,9 +2,9 @@
using System.Collections.Generic;
using System.Text;
-namespace JiShe.CollectBus.Analyzers
+namespace JiShe.CollectBus.Analyzers.Shared
{
- public interface ISourceAnalyzersProvider
+ public interface ISourceEntityAccessor
{
///
/// 获取属性值