Fix/context get generator service binding #148
Merged
Merged
Conversation
- 移除了对引用类型的自动服务绑定推断,避免将非上下文服务字段误判为服务依赖 - 更新了GetAll特性的行为描述,明确Service和Services绑定不会自动推断 - 添加了显式GetService特性的测试用例验证正确的绑定行为 - 从测试代码中移除了未使用的GetService扩展方法声明 - 为BattlePanel测试类添加了IStrategy服务集合字段以完善测试覆盖
- 重构了EnumerateCollectionTypeCandidates方法的调用方式 - 使用模式匹配简化了类型参数的提取逻辑 - 移除了不必要的SelectMany操作提高代码可读性 - 添加了空值检查增强代码健壮性 - 在方法末尾添加了必要的换行符保持代码格式一致
Reviewer's Guide调整 ContextGet 源生成器,使在使用 [GetAll] 时不再自动推断服务和服务集合绑定;为显式服务绑定添加回归测试,并更新 README,记录服务现在需要显式选择加入的新行为。 Sequence diagram for ContextGetGenerator handling GetAll with explicit GetServicesequenceDiagram
actor Developer
participant Compiler
participant ContextGetGenerator
participant BattlePanel
participant ContextAwareServiceExtensions
Developer->>Compiler: Build project containing BattlePanel
Compiler->>ContextGetGenerator: Invoke source generator
ContextGetGenerator->>BattlePanel: Scan attributes on BattlePanel
BattlePanel-->>ContextGetGenerator: GetAll on class
ContextGetGenerator->>BattlePanel: Enumerate fields
BattlePanel-->>ContextGetGenerator: _model: IInventoryModel
ContextGetGenerator->>ContextGetGenerator: TryCreateInferredBinding for _model
ContextGetGenerator-->>ContextGetGenerator: Recognize Model binding
BattlePanel-->>ContextGetGenerator: _service: IStrategy with GetService
ContextGetGenerator->>ContextGetGenerator: Skip inferred Service binding (opt in only)
ContextGetGenerator->>ContextGetGenerator: Create explicit Service binding from GetServiceAttribute
ContextGetGenerator-->>Compiler: Emit __InjectContextBindings_Generated
Compiler-->>BattlePanel: Merge partial type with generated method
Developer->>BattlePanel: Instantiate BattlePanel at runtime
BattlePanel->>BattlePanel: __InjectContextBindings_Generated()
BattlePanel->>ContextAwareServiceExtensions: GetModel~IInventoryModel~(this)
BattlePanel->>ContextAwareServiceExtensions: GetService~IStrategy~(this)
ContextAwareServiceExtensions-->>BattlePanel: Resolved IInventoryModel and IStrategy
Class diagram for ContextGetGenerator service binding behaviorclassDiagram
direction LR
class ContextGetGenerator {
+TryCreateInferredBinding(fieldSymbol, binding)
+TryResolveCollectionElement(targetType, elementType)
+EnumerateCollectionTypeCandidates(typeSymbol)
}
class BindingInfo {
+fieldSymbol
+kind
+serviceType
}
class BindingKind {
<<enumeration>>
Model
Models
System
Systems
Utility
Utilities
Service
Services
}
class GetAllAttribute {
<<attribute>>
+usage: Class
}
class GetServiceAttribute {
<<attribute>>
+usage: Field
}
class ContextAwareBase {
}
class IContextAware {
<<interface>>
}
class ContextAwareServiceExtensions {
+GetModel~T~(contextAware)
+GetModels~T~(contextAware)
+GetSystem~T~(contextAware)
+GetUtility~T~(contextAware)
+GetService~T~(contextAware)
}
class BattlePanel {
<<partial>>
-_model: IInventoryModel
-_service: IStrategy
-_services: IReadOnlyList~IStrategy~
+__InjectContextBindings_Generated()
}
class IInventoryModel {
<<interface>>
}
class IStrategy {
<<interface>>
}
class IModel {
<<interface>>
}
class ISystem {
<<interface>>
}
class IUtility {
<<interface>>
}
IContextAware <|.. ContextAwareBase
ContextAwareBase <|-- BattlePanel
BindingKind <.. BindingInfo
BindingInfo <.. ContextGetGenerator
GetAllAttribute <.. BattlePanel
GetServiceAttribute <.. BattlePanel
IInventoryModel <|.. IModel
IModel <.. IInventoryModel
ISystem <.. ISystem
IUtility <.. IUtility
ContextAwareServiceExtensions ..> BattlePanel : extension_methods
ContextGetGenerator ..> ContextAwareServiceExtensions : generates_calls
Flow diagram for inferred bindings under GetAll without service inferenceflowchart TD
A[Start: Field under GetAll] --> B{Is field a collection type?}
B -- Yes --> C[Call TryResolveCollectionElement]
C --> D{Element type is Model/System/Utility?}
D -- Yes --> E[Create BindingInfo with kind Models/Systems/Utilities]
D -- No --> F[No inferred binding]
B -- No --> G{Field type is Model/System/Utility?}
G -- Yes --> H[Create BindingInfo with kind Model/System/Utility]
G -- No --> I[No inferred binding]
E --> J[Return true]
H --> J
F --> K[Service collections stay opt in]
I --> L[Service bindings stay opt in]
K --> M[Require GetService or GetServices attribute]
L --> M
M --> N[End]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your Experience访问你的 dashboard 以:
Getting HelpOriginal review guide in EnglishReviewer's GuideAdjusts the ContextGet source generator so that service and service-collection bindings are no longer inferred automatically under [GetAll], adds regression tests for explicit service bindings, and updates the README to document the new opt-in behavior for services. Sequence diagram for ContextGetGenerator handling GetAll with explicit GetServicesequenceDiagram
actor Developer
participant Compiler
participant ContextGetGenerator
participant BattlePanel
participant ContextAwareServiceExtensions
Developer->>Compiler: Build project containing BattlePanel
Compiler->>ContextGetGenerator: Invoke source generator
ContextGetGenerator->>BattlePanel: Scan attributes on BattlePanel
BattlePanel-->>ContextGetGenerator: GetAll on class
ContextGetGenerator->>BattlePanel: Enumerate fields
BattlePanel-->>ContextGetGenerator: _model: IInventoryModel
ContextGetGenerator->>ContextGetGenerator: TryCreateInferredBinding for _model
ContextGetGenerator-->>ContextGetGenerator: Recognize Model binding
BattlePanel-->>ContextGetGenerator: _service: IStrategy with GetService
ContextGetGenerator->>ContextGetGenerator: Skip inferred Service binding (opt in only)
ContextGetGenerator->>ContextGetGenerator: Create explicit Service binding from GetServiceAttribute
ContextGetGenerator-->>Compiler: Emit __InjectContextBindings_Generated
Compiler-->>BattlePanel: Merge partial type with generated method
Developer->>BattlePanel: Instantiate BattlePanel at runtime
BattlePanel->>BattlePanel: __InjectContextBindings_Generated()
BattlePanel->>ContextAwareServiceExtensions: GetModel~IInventoryModel~(this)
BattlePanel->>ContextAwareServiceExtensions: GetService~IStrategy~(this)
ContextAwareServiceExtensions-->>BattlePanel: Resolved IInventoryModel and IStrategy
Class diagram for ContextGetGenerator service binding behaviorclassDiagram
direction LR
class ContextGetGenerator {
+TryCreateInferredBinding(fieldSymbol, binding)
+TryResolveCollectionElement(targetType, elementType)
+EnumerateCollectionTypeCandidates(typeSymbol)
}
class BindingInfo {
+fieldSymbol
+kind
+serviceType
}
class BindingKind {
<<enumeration>>
Model
Models
System
Systems
Utility
Utilities
Service
Services
}
class GetAllAttribute {
<<attribute>>
+usage: Class
}
class GetServiceAttribute {
<<attribute>>
+usage: Field
}
class ContextAwareBase {
}
class IContextAware {
<<interface>>
}
class ContextAwareServiceExtensions {
+GetModel~T~(contextAware)
+GetModels~T~(contextAware)
+GetSystem~T~(contextAware)
+GetUtility~T~(contextAware)
+GetService~T~(contextAware)
}
class BattlePanel {
<<partial>>
-_model: IInventoryModel
-_service: IStrategy
-_services: IReadOnlyList~IStrategy~
+__InjectContextBindings_Generated()
}
class IInventoryModel {
<<interface>>
}
class IStrategy {
<<interface>>
}
class IModel {
<<interface>>
}
class ISystem {
<<interface>>
}
class IUtility {
<<interface>>
}
IContextAware <|.. ContextAwareBase
ContextAwareBase <|-- BattlePanel
BindingKind <.. BindingInfo
BindingInfo <.. ContextGetGenerator
GetAllAttribute <.. BattlePanel
GetServiceAttribute <.. BattlePanel
IInventoryModel <|.. IModel
IModel <.. IInventoryModel
ISystem <.. ISystem
IUtility <.. IUtility
ContextAwareServiceExtensions ..> BattlePanel : extension_methods
ContextGetGenerator ..> ContextAwareServiceExtensions : generates_calls
Flow diagram for inferred bindings under GetAll without service inferenceflowchart TD
A[Start: Field under GetAll] --> B{Is field a collection type?}
B -- Yes --> C[Call TryResolveCollectionElement]
C --> D{Element type is Model/System/Utility?}
D -- Yes --> E[Create BindingInfo with kind Models/Systems/Utilities]
D -- No --> F[No inferred binding]
B -- No --> G{Field type is Model/System/Utility?}
G -- Yes --> H[Create BindingInfo with kind Model/System/Utility]
G -- No --> I[No inferred binding]
E --> J[Return true]
H --> J
F --> K[Service collections stay opt in]
I --> L[Service bindings stay opt in]
K --> M[Require GetService or GetServices attribute]
L --> M
M --> N[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 28, 2026 11:56a.m. | Review ↗ | |
| Secrets | Mar 28, 2026 11:56a.m. | Review ↗ |
- 将嵌套循环重构为使用 SelectMany 扁平化集合类型参数 - 简化了候选元素类型的遍历逻辑 - 提高了代码可读性和性能 - 移除了不必要的 continue 语句 - 保持了原有的类型匹配功能不变
- 在测试中添加换行符标准化功能,确保跨平台测试一致性 - 修复ContextGetGenerator中集合类型候选检测逻辑,跳过无效类型参数 - 添加针对可空服务字段的单元测试用例 - 优化生成器对不同系统换行符的处理机制
- 在 GFramework.Godot.SourceGenerators.Tests 中添加 Microsoft.CodeAnalysis 相关引用 - 在 GFramework.SourceGenerators 中添加 ImmutableCollections 和 StringBuilder 引用 - 在 GFramework.SourceGenerators 中添加 Common.Extensions 引用 - 在 GFramework.SourceGenerators.Tests 中添加测试框架相关引用 - 统一全局引用的组织结构
This was referenced May 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary by Sourcery
澄清并强制规定:在使用 [GetAll] 时,服务绑定应保持为“显式选择加入”(opt-in),而不是从任意引用类型字段中推断而来。
Bug 修复:
增强功能:
文档:
测试:
Original summary in English
Summary by Sourcery
Clarify and enforce that service bindings under [GetAll] remain opt-in rather than inferred from arbitrary reference-type fields.
Bug Fixes:
Enhancements:
Documentation:
Tests: