Feat/add priority service resolution#80
Conversation
- 在 ArchitectureContext 中添加 GetServicesByPriority、GetSystemsByPriority、 GetModelsByPriority 和 GetUtilitiesByPriority 方法 - 在 ContextAwareServiceExtensions 中添加对应的扩展方法支持按优先级获取实例 - 在 MicrosoftDiContainer 中实现 GetAllByPriority 方法和 SortByPriority 排序逻辑 - 在抽象层定义 IPrioritized 接口用于标记可排序的服务组件 - 为 PauseToken 添加完整的相等性比较和字符串转换方法 - 添加全面的单元测试验证优先级排序功能的正确性
- 新增 PriorityGenerator 源生成器,自动生成 IPrioritized 接口实现 - 添加 PriorityAttribute 特性,用于标记类的优先级值 - 实现 PriorityUsageAnalyzer 分析器,检测优先级使用建议 - 添加预定义的 PriorityGroup 常量,提供标准优先级分组 - 在 AnalyzerReleases.Unshipped.md 中注册新的诊断规则 - 更新项目依赖,升级 Meziantou.Analyzer 和 Polyfill 版本 - 为测试项目添加源生成器项目引用 - 添加 PriorityGenerator 的快照测试用例
Reviewer's Guide在整个 IoC 容器和架构上下文中新增基于优先级的解析机制,引入 IPrioritized 和 PriorityAttribute,并通过源生成器/分析器自动实现和校验优先级用法,同时提供围绕优先级排序与生成器行为的完整单元测试和快照测试。 通过具备上下文感知扩展方法解析带优先级服务的时序图sequenceDiagram
actor Client
participant ContextAware as IContextAware
participant Extensions as ContextAwareServiceExtensions
participant ArchCtx as ArchitectureContext
participant Container as MicrosoftDiContainer
Client->>ContextAware: GetServicesByPriority~IMyService~() extension
activate ContextAware
ContextAware->>Extensions: GetServicesByPriority~IMyService~(contextAware)
activate Extensions
Extensions->>ContextAware: GetContext()
ContextAware-->>Extensions: IArchitectureContext
Extensions->>ArchCtx: GetServicesByPriority~IMyService~()
activate ArchCtx
ArchCtx->>Container: GetAllByPriority~IMyService~()
activate Container
Container->>Container: GetAll~IMyService~()
Container->>Container: SortByPriority~IMyService~(services)
Container-->>ArchCtx: IReadOnlyList~IMyService~
deactivate Container
ArchCtx-->>Extensions: IReadOnlyList~IMyService~
deactivate ArchCtx
Extensions-->>Client: IReadOnlyList~IMyService~
deactivate Extensions
deactivate ContextAware
优先级抽象、特性、生成器和分析器的类图classDiagram
direction TB
class IPrioritized {
<<interface>>
+int Priority
}
class PriorityGroup {
<<static>>
+const int Critical
+const int High
+const int Normal
+const int Low
+const int Deferred
}
class PriorityAttribute {
+PriorityAttribute(int value)
+int Value
}
class PriorityDiagnostic {
<<static>>
+DiagnosticDescriptor OnlyApplyToClass
+DiagnosticDescriptor AlreadyImplemented
+DiagnosticDescriptor MustBePartial
+DiagnosticDescriptor InvalidValue
}
class PriorityGenerator {
<<generator>>
-string AttributeMetadataName
-string AttributeShortNameWithoutSuffix
+bool ValidateSymbol(SourceProductionContext context, Compilation compilation, ClassDeclarationSyntax syntax, INamedTypeSymbol symbol, AttributeData attr)
+string Generate(SourceProductionContext context, Compilation compilation, INamedTypeSymbol symbol, AttributeData attr)
+string GetHintName(INamedTypeSymbol symbol)
}
class PriorityUsageAnalyzer {
<<analyzer>>
-const string DiagnosticId
-static DiagnosticDescriptor Rule
+Initialize(AnalysisContext context)
}
class MetadataAttributeClassGeneratorBase {
<<abstract>>
+Execute()
}
class DiagnosticDescriptor
class SourceProductionContext
class Compilation
class ClassDeclarationSyntax
class INamedTypeSymbol
class AttributeData
class AnalysisContext
PriorityAttribute ..|> Attribute
PriorityGenerator ..|> MetadataAttributeClassGeneratorBase
PriorityUsageAnalyzer ..|> DiagnosticAnalyzer
PriorityGenerator ..> PriorityAttribute : reads
PriorityGenerator ..> IPrioritized : generates implementation
PriorityGenerator ..> PriorityDiagnostic : reports
PriorityUsageAnalyzer ..> IPrioritized : checks implementations
PriorityUsageAnalyzer ..> PriorityDiagnostic : uses rule ids
IPrioritized <.. PriorityGroup : uses constants
class Attribute
class DiagnosticAnalyzer
IoC 与架构优先级解析 API 的类图classDiagram
direction TB
class IIocContainer {
<<interface>>
+IReadOnlyList~T~ GetAll~T~()
+IReadOnlyList~T~ GetAllSorted~T~(Comparison~T~ comparison)
+IReadOnlyList~T~ GetAllByPriority~T~()
+IReadOnlyList~object~ GetAllByPriority(Type type)
}
class MicrosoftDiContainer {
+IReadOnlyList~T~ GetAll~T~()
+IReadOnlyList~T~ GetAllSorted~T~(Comparison~T~ comparison)
+IReadOnlyList~T~ GetAllByPriority~T~()
+IReadOnlyList~object~ GetAllByPriority(Type type)
-IReadOnlyList~T~ SortByPriority~T~(IReadOnlyList~T~ services)
}
class IArchitectureContext {
<<interface>>
+IReadOnlyList~TService~ GetServices~TService~()
+IReadOnlyList~TSystem~ GetSystems~TSystem~()
+IReadOnlyList~TModel~ GetModels~TModel~()
+IReadOnlyList~TUtility~ GetUtilities~TUtility~()
+IReadOnlyList~TService~ GetServicesByPriority~TService~()
+IReadOnlyList~TSystem~ GetSystemsByPriority~TSystem~()
+IReadOnlyList~TModel~ GetModelsByPriority~TModel~()
+IReadOnlyList~TUtility~ GetUtilitiesByPriority~TUtility~()
}
class ArchitectureContext {
-IIocContainer _container
+IReadOnlyList~TService~ GetServices~TService~()
+IReadOnlyList~TSystem~ GetSystems~TSystem~()
+IReadOnlyList~TModel~ GetModels~TModel~()
+IReadOnlyList~TUtility~ GetUtilities~TUtility~()
+IReadOnlyList~TService~ GetServicesByPriority~TService~()
+IReadOnlyList~TSystem~ GetSystemsByPriority~TSystem~()
+IReadOnlyList~TModel~ GetModelsByPriority~TModel~()
+IReadOnlyList~TUtility~ GetUtilitiesByPriority~TUtility~()
}
class IContextAware {
<<interface>>
+IArchitectureContext GetContext()
}
class ContextAwareServiceExtensions {
<<static>>
+IReadOnlyList~TService~ GetServicesByPriority~TService~(IContextAware contextAware)
+IReadOnlyList~TSystem~ GetSystemsByPriority~TSystem~(IContextAware contextAware)
+IReadOnlyList~TModel~ GetModelsByPriority~TModel~(IContextAware contextAware)
+IReadOnlyList~TUtility~ GetUtilitiesByPriority~TUtility~(IContextAware contextAware)
}
class IPrioritized {
<<interface>>
+int Priority
}
MicrosoftDiContainer ..|> IIocContainer
ArchitectureContext ..|> IArchitectureContext
ArchitectureContext o--> IIocContainer : uses
ContextAwareServiceExtensions ..> IContextAware : extension
ContextAwareServiceExtensions ..> IArchitectureContext : calls
IIocContainer ..> IPrioritized : sort by Priority
ArchitectureContext ..> IIocContainer : GetAllByPriority
class Comparison~T~
class Type
class IReadOnlyList~T~
PriorityUsageAnalyzer 决策逻辑的流程图flowchart TD
A["Start: InvocationOperation"] --> B{"TargetMethod.Name == GetAll?"}
B -- No --> Z["Exit"]
B -- Yes --> C{"Is generic and has 1 type argument?"}
C -- No --> Z
C -- Yes --> D{"Containing type is IIocContainer or IArchitectureContext?"}
D -- No --> Z
D -- Yes --> E["Get type argument T"]
E --> F{"T implements IPrioritized?"}
F -- No --> Z
F -- Yes --> G["Report diagnostic: suggest GetAllByPriority<T>()"]
G --> Z
Z["End"]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your Experience访问你的 dashboard 以:
Getting HelpOriginal review guide in EnglishReviewer's GuideAdds a priority-based resolution mechanism across the IoC container and architecture context, introduces IPrioritized and PriorityAttribute plus source generator/analyzers to auto-implement and validate priority usage, and supplies comprehensive unit and snapshot tests around priority ordering and generator behavior. Sequence diagram for resolving prioritized services via context-aware extensionssequenceDiagram
actor Client
participant ContextAware as IContextAware
participant Extensions as ContextAwareServiceExtensions
participant ArchCtx as ArchitectureContext
participant Container as MicrosoftDiContainer
Client->>ContextAware: GetServicesByPriority~IMyService~() extension
activate ContextAware
ContextAware->>Extensions: GetServicesByPriority~IMyService~(contextAware)
activate Extensions
Extensions->>ContextAware: GetContext()
ContextAware-->>Extensions: IArchitectureContext
Extensions->>ArchCtx: GetServicesByPriority~IMyService~()
activate ArchCtx
ArchCtx->>Container: GetAllByPriority~IMyService~()
activate Container
Container->>Container: GetAll~IMyService~()
Container->>Container: SortByPriority~IMyService~(services)
Container-->>ArchCtx: IReadOnlyList~IMyService~
deactivate Container
ArchCtx-->>Extensions: IReadOnlyList~IMyService~
deactivate ArchCtx
Extensions-->>Client: IReadOnlyList~IMyService~
deactivate Extensions
deactivate ContextAware
Class diagram for priority abstractions, attribute, generator, and analyzerclassDiagram
direction TB
class IPrioritized {
<<interface>>
+int Priority
}
class PriorityGroup {
<<static>>
+const int Critical
+const int High
+const int Normal
+const int Low
+const int Deferred
}
class PriorityAttribute {
+PriorityAttribute(int value)
+int Value
}
class PriorityDiagnostic {
<<static>>
+DiagnosticDescriptor OnlyApplyToClass
+DiagnosticDescriptor AlreadyImplemented
+DiagnosticDescriptor MustBePartial
+DiagnosticDescriptor InvalidValue
}
class PriorityGenerator {
<<generator>>
-string AttributeMetadataName
-string AttributeShortNameWithoutSuffix
+bool ValidateSymbol(SourceProductionContext context, Compilation compilation, ClassDeclarationSyntax syntax, INamedTypeSymbol symbol, AttributeData attr)
+string Generate(SourceProductionContext context, Compilation compilation, INamedTypeSymbol symbol, AttributeData attr)
+string GetHintName(INamedTypeSymbol symbol)
}
class PriorityUsageAnalyzer {
<<analyzer>>
-const string DiagnosticId
-static DiagnosticDescriptor Rule
+Initialize(AnalysisContext context)
}
class MetadataAttributeClassGeneratorBase {
<<abstract>>
+Execute()
}
class DiagnosticDescriptor
class SourceProductionContext
class Compilation
class ClassDeclarationSyntax
class INamedTypeSymbol
class AttributeData
class AnalysisContext
PriorityAttribute ..|> Attribute
PriorityGenerator ..|> MetadataAttributeClassGeneratorBase
PriorityUsageAnalyzer ..|> DiagnosticAnalyzer
PriorityGenerator ..> PriorityAttribute : reads
PriorityGenerator ..> IPrioritized : generates implementation
PriorityGenerator ..> PriorityDiagnostic : reports
PriorityUsageAnalyzer ..> IPrioritized : checks implementations
PriorityUsageAnalyzer ..> PriorityDiagnostic : uses rule ids
IPrioritized <.. PriorityGroup : uses constants
class Attribute
class DiagnosticAnalyzer
Class diagram for IoC and architecture priority resolution APIsclassDiagram
direction TB
class IIocContainer {
<<interface>>
+IReadOnlyList~T~ GetAll~T~()
+IReadOnlyList~T~ GetAllSorted~T~(Comparison~T~ comparison)
+IReadOnlyList~T~ GetAllByPriority~T~()
+IReadOnlyList~object~ GetAllByPriority(Type type)
}
class MicrosoftDiContainer {
+IReadOnlyList~T~ GetAll~T~()
+IReadOnlyList~T~ GetAllSorted~T~(Comparison~T~ comparison)
+IReadOnlyList~T~ GetAllByPriority~T~()
+IReadOnlyList~object~ GetAllByPriority(Type type)
-IReadOnlyList~T~ SortByPriority~T~(IReadOnlyList~T~ services)
}
class IArchitectureContext {
<<interface>>
+IReadOnlyList~TService~ GetServices~TService~()
+IReadOnlyList~TSystem~ GetSystems~TSystem~()
+IReadOnlyList~TModel~ GetModels~TModel~()
+IReadOnlyList~TUtility~ GetUtilities~TUtility~()
+IReadOnlyList~TService~ GetServicesByPriority~TService~()
+IReadOnlyList~TSystem~ GetSystemsByPriority~TSystem~()
+IReadOnlyList~TModel~ GetModelsByPriority~TModel~()
+IReadOnlyList~TUtility~ GetUtilitiesByPriority~TUtility~()
}
class ArchitectureContext {
-IIocContainer _container
+IReadOnlyList~TService~ GetServices~TService~()
+IReadOnlyList~TSystem~ GetSystems~TSystem~()
+IReadOnlyList~TModel~ GetModels~TModel~()
+IReadOnlyList~TUtility~ GetUtilities~TUtility~()
+IReadOnlyList~TService~ GetServicesByPriority~TService~()
+IReadOnlyList~TSystem~ GetSystemsByPriority~TSystem~()
+IReadOnlyList~TModel~ GetModelsByPriority~TModel~()
+IReadOnlyList~TUtility~ GetUtilitiesByPriority~TUtility~()
}
class IContextAware {
<<interface>>
+IArchitectureContext GetContext()
}
class ContextAwareServiceExtensions {
<<static>>
+IReadOnlyList~TService~ GetServicesByPriority~TService~(IContextAware contextAware)
+IReadOnlyList~TSystem~ GetSystemsByPriority~TSystem~(IContextAware contextAware)
+IReadOnlyList~TModel~ GetModelsByPriority~TModel~(IContextAware contextAware)
+IReadOnlyList~TUtility~ GetUtilitiesByPriority~TUtility~(IContextAware contextAware)
}
class IPrioritized {
<<interface>>
+int Priority
}
MicrosoftDiContainer ..|> IIocContainer
ArchitectureContext ..|> IArchitectureContext
ArchitectureContext o--> IIocContainer : uses
ContextAwareServiceExtensions ..> IContextAware : extension
ContextAwareServiceExtensions ..> IArchitectureContext : calls
IIocContainer ..> IPrioritized : sort by Priority
ArchitectureContext ..> IIocContainer : GetAllByPriority
class Comparison~T~
class Type
class IReadOnlyList~T~
Flow diagram for PriorityUsageAnalyzer decision logicflowchart TD
A["Start: InvocationOperation"] --> B{"TargetMethod.Name == GetAll?"}
B -- No --> Z["Exit"]
B -- Yes --> C{"Is generic and has 1 type argument?"}
C -- No --> Z
C -- Yes --> D{"Containing type is IIocContainer or IArchitectureContext?"}
D -- No --> Z
D -- Yes --> E["Get type argument T"]
E --> F{"T implements IPrioritized?"}
F -- No --> Z
F -- Yes --> G["Report diagnostic: suggest GetAllByPriority<T>()"]
G --> Z
Z["End"]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
|
Overall Grade |
Security Reliability Complexity Hygiene |
Code Review Summary
| Analyzer | Status | Updated (UTC) | Details |
|---|---|---|---|
| C# | Mar 5, 2026 2:47p.m. | Review ↗ | |
| Secrets | Mar 5, 2026 2:47p.m. | Review ↗ |
There was a problem hiding this comment.
Hey - 我发现了 3 个问题,并留下了一些总体反馈:
PriorityUsageAnalyzer使用了硬编码的诊断 IDGF_Priority_Usage_001,而AnalyzerReleases.Unshipped.md注册的是GF_Priority_001–GF_Priority_004;建议对齐诊断 ID,并使用已有的PriorityDiagnostic描述符,这样分析器的诊断才能被发现,并与发布元数据保持一致。- 在
PriorityGenerator.GetHintName中,仅使用symbol.Name作为生成文件名,在存在嵌套类型或不同命名空间下同名类型时会导致冲突;建议在提示名称中包含命名空间和嵌套信息(例如使用元数据名称),以保证唯一性。 - 当前优先级排序逻辑只实现于
MicrosoftDiContainer.SortByPriority中;由于现在相同语义也通过ArchitectureContext和多个扩展方法暴露出来,建议将该排序行为集中到一个共享的辅助方法中,以避免将来规则变更时出现细微差异。
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `PriorityUsageAnalyzer` uses the hard-coded diagnostic ID `GF_Priority_Usage_001`, whereas `AnalyzerReleases.Unshipped.md` registers `GF_Priority_001`–`GF_Priority_004`; consider aligning the ID and using the existing `PriorityDiagnostic` descriptors so the analyzer’s diagnostics are discoverable and consistent with the release metadata.
- In `PriorityGenerator.GetHintName`, using only `symbol.Name` for the generated file name can cause collisions for nested types or types with the same name in different namespaces; consider including namespace and nesting (e.g., metadata name) in the hint name to ensure uniqueness.
- The priority-sorting logic is currently implemented only inside `MicrosoftDiContainer.SortByPriority`; since the same semantics are now exposed via `ArchitectureContext` and multiple extension methods, it may be worthwhile to centralize this sorting behavior in a shared helper to avoid subtle divergence if the rules change later.
## Individual Comments
### Comment 1
<location path="GFramework.Core/ioc/MicrosoftDiContainer.cs" line_range="638-595" />
<code_context>
+ var list = services.ToList();
+
+ // 稳定排序:相同优先级保持注册顺序
+ list.Sort((a, b) =>
+ {
+ var priorityA = a is IPrioritized pa ? pa.Priority : 0;
+ var priorityB = b is IPrioritized pb ? pb.Priority : 0;
+ return priorityA.CompareTo(priorityB); // 升序
+ });
+
+ return list;
+ }
+
</code_context>
<issue_to_address>
**issue (bug_risk):** The use of List.Sort here contradicts the "stable sort" guarantee in the comment and tests.
Because List<T>.Sort is not stable, items with the same Priority may not preserve registration order, causing flaky behavior that contradicts the documented contract. To ensure stability, use an approach that includes the original index in the sort key (e.g., sort by (priority, index)) or use OrderBy with an index selector instead of List.Sort.
</issue_to_address>
### Comment 2
<location path="GFramework.SourceGenerators/bases/PriorityGenerator.cs" line_range="115-122" />
<code_context>
+ ? $"<{string.Join(", ", symbol.TypeParameters.Select(tp => tp.Name))}>"
+ : string.Empty;
+
+ sb.AppendLine(
+ $"partial class {symbol.Name}{typeParameters} : global::GFramework.Core.Abstractions.bases.IPrioritized");
+ sb.AppendLine("{");
+ sb.AppendLine(" /// <summary>");
+ sb.AppendLine($" /// 获取优先级值: {priorityValue}");
+ sb.AppendLine(" /// </summary>");
+ sb.AppendLine($" public int Priority => {priorityValue};");
+ sb.AppendLine("}");
+
+ return sb.ToString().TrimEnd();
</code_context>
<issue_to_address>
**issue:** Generated partial class does not account for nesting, which will break for nested types.
For nested classes, `symbol.Name` only gives the innermost type name, so the generator emits a top-level partial in the namespace instead of matching the original nesting (e.g., `OuterClass.NestedSystem`). This will fail to compile for nested (and some generic/nested) types. Consider emitting the full containing type hierarchy (e.g., wrapping in partials for containing types or constructing the full nested type name) so the generated partial structurally matches the original declaration.
</issue_to_address>
### Comment 3
<location path="GFramework.Core/ioc/MicrosoftDiContainer.cs" line_range="613" />
<code_context>
+
+ /// <summary>
+ /// 获取指定类型的所有实例,并按优先级排序
+ /// 实现 IPrioritized 接口的服务将按值越小优先级越高)
+ /// 未实现 IPrioritized 的服务将使用默认优先级 0
+ /// </summary>
</code_context>
<issue_to_address>
**nitpick (typo):** Minor typo in XML documentation for GetAllByPriority(Type).
The Chinese summary line is missing an opening parenthesis before “值”, e.g. it should read “按优先级排序(数值越小优先级越高)” to be clear and grammatically correct.
</issue_to_address>Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Original comment in English
Hey - I've found 3 issues, and left some high level feedback:
- The
PriorityUsageAnalyzeruses the hard-coded diagnostic IDGF_Priority_Usage_001, whereasAnalyzerReleases.Unshipped.mdregistersGF_Priority_001–GF_Priority_004; consider aligning the ID and using the existingPriorityDiagnosticdescriptors so the analyzer’s diagnostics are discoverable and consistent with the release metadata. - In
PriorityGenerator.GetHintName, using onlysymbol.Namefor the generated file name can cause collisions for nested types or types with the same name in different namespaces; consider including namespace and nesting (e.g., metadata name) in the hint name to ensure uniqueness. - The priority-sorting logic is currently implemented only inside
MicrosoftDiContainer.SortByPriority; since the same semantics are now exposed viaArchitectureContextand multiple extension methods, it may be worthwhile to centralize this sorting behavior in a shared helper to avoid subtle divergence if the rules change later.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `PriorityUsageAnalyzer` uses the hard-coded diagnostic ID `GF_Priority_Usage_001`, whereas `AnalyzerReleases.Unshipped.md` registers `GF_Priority_001`–`GF_Priority_004`; consider aligning the ID and using the existing `PriorityDiagnostic` descriptors so the analyzer’s diagnostics are discoverable and consistent with the release metadata.
- In `PriorityGenerator.GetHintName`, using only `symbol.Name` for the generated file name can cause collisions for nested types or types with the same name in different namespaces; consider including namespace and nesting (e.g., metadata name) in the hint name to ensure uniqueness.
- The priority-sorting logic is currently implemented only inside `MicrosoftDiContainer.SortByPriority`; since the same semantics are now exposed via `ArchitectureContext` and multiple extension methods, it may be worthwhile to centralize this sorting behavior in a shared helper to avoid subtle divergence if the rules change later.
## Individual Comments
### Comment 1
<location path="GFramework.Core/ioc/MicrosoftDiContainer.cs" line_range="638-595" />
<code_context>
+ var list = services.ToList();
+
+ // 稳定排序:相同优先级保持注册顺序
+ list.Sort((a, b) =>
+ {
+ var priorityA = a is IPrioritized pa ? pa.Priority : 0;
+ var priorityB = b is IPrioritized pb ? pb.Priority : 0;
+ return priorityA.CompareTo(priorityB); // 升序
+ });
+
+ return list;
+ }
+
</code_context>
<issue_to_address>
**issue (bug_risk):** The use of List.Sort here contradicts the "stable sort" guarantee in the comment and tests.
Because List<T>.Sort is not stable, items with the same Priority may not preserve registration order, causing flaky behavior that contradicts the documented contract. To ensure stability, use an approach that includes the original index in the sort key (e.g., sort by (priority, index)) or use OrderBy with an index selector instead of List.Sort.
</issue_to_address>
### Comment 2
<location path="GFramework.SourceGenerators/bases/PriorityGenerator.cs" line_range="115-122" />
<code_context>
+ ? $"<{string.Join(", ", symbol.TypeParameters.Select(tp => tp.Name))}>"
+ : string.Empty;
+
+ sb.AppendLine(
+ $"partial class {symbol.Name}{typeParameters} : global::GFramework.Core.Abstractions.bases.IPrioritized");
+ sb.AppendLine("{");
+ sb.AppendLine(" /// <summary>");
+ sb.AppendLine($" /// 获取优先级值: {priorityValue}");
+ sb.AppendLine(" /// </summary>");
+ sb.AppendLine($" public int Priority => {priorityValue};");
+ sb.AppendLine("}");
+
+ return sb.ToString().TrimEnd();
</code_context>
<issue_to_address>
**issue:** Generated partial class does not account for nesting, which will break for nested types.
For nested classes, `symbol.Name` only gives the innermost type name, so the generator emits a top-level partial in the namespace instead of matching the original nesting (e.g., `OuterClass.NestedSystem`). This will fail to compile for nested (and some generic/nested) types. Consider emitting the full containing type hierarchy (e.g., wrapping in partials for containing types or constructing the full nested type name) so the generated partial structurally matches the original declaration.
</issue_to_address>
### Comment 3
<location path="GFramework.Core/ioc/MicrosoftDiContainer.cs" line_range="613" />
<code_context>
+
+ /// <summary>
+ /// 获取指定类型的所有实例,并按优先级排序
+ /// 实现 IPrioritized 接口的服务将按值越小优先级越高)
+ /// 未实现 IPrioritized 的服务将使用默认优先级 0
+ /// </summary>
</code_context>
<issue_to_address>
**nitpick (typo):** Minor typo in XML documentation for GetAllByPriority(Type).
The Chinese summary line is missing an opening parenthesis before “值”, e.g. it should read “按优先级排序(数值越小优先级越高)” to be clear and grammatically correct.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
- 修改 MicrosoftDiContainer 中 GetAllByPriority 方法的排序逻辑,使用 OrderBy 确保稳定排序 - 修正注释中的中文描述,明确优先级排序规则 - 将 PriorityUsageAnalyzer 中的硬编码诊断规则替换为统一的 PriorityDiagnostic - 在 PriorityGenerator 中添加对嵌套类的支持检查,报告 GF_Priority_005 错误 - 改进生成文件的命名策略,使用完整元数据名称避免冲突 - 更新 AnalyzerReleases.Unshipped.md 文档,添加新的诊断规则说明 - 移除 PriorityGeneratorSnapshotTests 中关于嵌套类的测试用例
Summary by Sourcery
添加一个支持优先级的抽象和源代码生成器,并在 IoC 容器和架构上下文中集成基于优先级的解析机制。
New Features:
IPrioritized接口、PriorityGroup常量以及PriorityAttribute,以声明式方式为组件分配执行优先级。PriorityGenerator源代码生成器和PriorityUsageAnalyzer,用于自动实现IPrioritized并建议使用支持优先级的解析方法。Enhancements:
PauseToken补充更丰富的 XML 文档,以提高使用说明的清晰度。Tests:
PriorityGenerator源代码生成器添加快照测试,用于验证针对各种类形式生成的代码。Original summary in English
Summary by Sourcery
Add a priority-aware abstraction and source generator, and integrate priority-based resolution across the IoC container and architecture context.
New Features:
Enhancements:
Tests: