Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/agents/DevOps.agent.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: "Use when: managing CI/CD pipelines, GitHub Actions workflows, build/test/pack/publish automation, NuGet Trusted Publishing, or release processes. Handles .github/workflows/ files and DevOps configuration."
model: GPT-5.4 (copilot)
tools: [vscode/memory, vscode/askQuestions, execute/getTerminalOutput, execute/runInTerminal, read, agent, 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', edit, search, web, github/get_copilot_job_status, github/get_file_contents, github/get_latest_release, github/get_release_by_tag, github/get_tag, github/issue_read, github/list_branches, github/list_releases, github/list_tags, github/pull_request_read, github/search_code, github/search_issues, github/search_pull_requests, github/search_repositories, github.vscode-pull-request-github/notification_fetch, todo]
tools: [vscode/askQuestions, vscode/memory, vscode/resolveMemoryFileUri, execute/getTerminalOutput, execute/runInTerminal, read, agent, edit, search, web, github/get_copilot_job_status, github/get_file_contents, github/get_latest_release, github/get_release_by_tag, github/get_tag, github/issue_read, github/list_branches, github/list_releases, github/list_tags, github/pull_request_read, github/search_code, github/search_issues, github/search_pull_requests, github/search_repositories, 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', todo, github.vscode-pull-request-github/notification_fetch]
agents: ["Explore"]
user-invocable: true
argument-hint: "Describe the CI/CD change: add workflow, fix pipeline, update publish config, etc."
Expand Down
2 changes: 1 addition & 1 deletion .github/agents/Doc.agent.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: "Use when: writing or updating user-facing documentation files (docs/ folder). Creates progressive, beginner-friendly guides with generated code examples for the SourceGen repository."
model: Claude Opus 4.6 (copilot)
tools: [vscode/memory, vscode/askQuestions, execute/getTerminalOutput, execute/runInTerminal, read, agent, codegraphcontext/analyze_code_relationships, codegraphcontext/find_code, codegraphcontext/get_repository_stats, 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', edit, search, web, todo]
tools: [vscode/askQuestions, vscode/memory, vscode/resolveMemoryFileUri, execute/getTerminalOutput, execute/runInTerminal, read, agent, edit, search, web, codegraphcontext/analyze_code_relationships, codegraphcontext/find_code, codegraphcontext/get_repository_stats, 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', todo]
agents: ["Explore", "DocReview"]
user-invocable: true
argument-hint: "Provide the documentation topic or feature to document, and which doc files to create or update"
Expand Down
2 changes: 1 addition & 1 deletion .github/agents/DocReview.agent.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: "Use when: reviewing completed documentation updates under docs/ for accuracy, consistency, links, and generated code examples."
model: GPT-5.4 (copilot)
tools: [vscode/memory, read, 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', search, web, todo]
tools: [vscode/memory, vscode/resolveMemoryFileUri, read, search, web, 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', todo]
agents: []
user-invocable: false
argument-hint: "Provide changed docs files and related source/spec paths to validate"
Expand Down
2 changes: 1 addition & 1 deletion .github/agents/Explore.agent.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: "Fast read-only codebase exploration and Q&A subagent. Prefer over manually chaining multiple search and file-reading operations to avoid cluttering the main conversation. Safe to call in parallel. Specify thoroughness: quick, medium, or thorough."
model: Claude Haiku 4.5 (copilot)
tools: [vscode/memory, execute/getTerminalOutput, execute/testFailure, read, codegraphcontext/analyze_code_relationships, codegraphcontext/calculate_cyclomatic_complexity, codegraphcontext/execute_cypher_query, codegraphcontext/find_code, codegraphcontext/find_dead_code, codegraphcontext/find_most_complex_functions, codegraphcontext/get_repository_stats, codegraphcontext/load_bundle, codegraphcontext/search_registry_bundles, codegraphcontext/visualize_graph_query, 'microsoft/markitdown/*', 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', search, web, github/get_commit, github/get_file_contents, github/issue_read, github/search_code, github/search_issues, github/search_pull_requests, github/search_repositories, github.vscode-pull-request-github/issue_fetch, github.vscode-pull-request-github/labels_fetch, github.vscode-pull-request-github/notification_fetch, github.vscode-pull-request-github/doSearch, github.vscode-pull-request-github/activePullRequest, github.vscode-pull-request-github/pullRequestStatusChecks, github.vscode-pull-request-github/openPullRequest]
tools: [vscode/memory, vscode/resolveMemoryFileUri, execute/getTerminalOutput, execute/testFailure, read, search, web, github/get_commit, github/get_file_contents, github/issue_read, github/search_code, github/search_issues, github/search_pull_requests, github/search_repositories, codegraphcontext/analyze_code_relationships, codegraphcontext/calculate_cyclomatic_complexity, codegraphcontext/execute_cypher_query, codegraphcontext/find_code, codegraphcontext/find_dead_code, codegraphcontext/find_most_complex_functions, codegraphcontext/get_repository_stats, codegraphcontext/load_bundle, codegraphcontext/search_registry_bundles, codegraphcontext/visualize_graph_query, 'microsoft/markitdown/*', 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', github.vscode-pull-request-github/issue_fetch, github.vscode-pull-request-github/labels_fetch, github.vscode-pull-request-github/notification_fetch, github.vscode-pull-request-github/doSearch, github.vscode-pull-request-github/activePullRequest, github.vscode-pull-request-github/pullRequestStatusChecks, github.vscode-pull-request-github/openPullRequest]
agents: []
user-invocable: false
argument-hint: "Describe WHAT you're looking for and desired thoroughness (quick/medium/thorough)"
Expand Down
4 changes: 2 additions & 2 deletions .github/agents/Implement.agent.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: "Use when: implementing approved plan from /memories/session/plan.md. Executes code changes, runs tests, and follows project conventions."
model: GPT-5.4 (copilot)
tools: [vscode/memory, execute, read, 'codegraphcontext/*', 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', edit, search, web, todo]
model: Claude Sonnet 4.6 (copilot)
tools: [vscode/memory, vscode/resolveMemoryFileUri, execute, read, edit, search, web, 'codegraphcontext/*', 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', todo]
agents: []
user-invocable: false
argument-hint: "Implement the approved plan stored in /memories/session/plan.md"
Expand Down
2 changes: 1 addition & 1 deletion .github/agents/Orchestrator.agent.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: "Use when: implementing features, fixing bugs, or making code changes that require planning, approval, and review. Analyzes requirements, writes plan.md, and delegates to subagents."
model: Claude Opus 4.6 (copilot)
tools: [vscode/memory, vscode/askQuestions, execute/getTerminalOutput, execute/testFailure, read, agent, 'codegraphcontext/*', 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', search, web, github/add_reply_to_pull_request_comment, github/get_commit, github/get_copilot_job_status, github/issue_read, github/pull_request_read, github/search_issues, github/search_pull_requests, vscode.mermaid-chat-features/renderMermaidDiagram, github.vscode-pull-request-github/issue_fetch, github.vscode-pull-request-github/labels_fetch, github.vscode-pull-request-github/notification_fetch, github.vscode-pull-request-github/doSearch, github.vscode-pull-request-github/activePullRequest, github.vscode-pull-request-github/pullRequestStatusChecks, github.vscode-pull-request-github/openPullRequest, todo]
tools: [vscode/askQuestions, vscode/memory, vscode/resolveMemoryFileUri, execute/getTerminalOutput, execute/testFailure, read, agent, search, web, github/add_reply_to_pull_request_comment, github/get_commit, github/get_copilot_job_status, github/issue_read, github/pull_request_read, github/search_issues, github/search_pull_requests, 'codegraphcontext/*', 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', todo, vscode.mermaid-chat-features/renderMermaidDiagram, github.vscode-pull-request-github/issue_fetch, github.vscode-pull-request-github/labels_fetch, github.vscode-pull-request-github/notification_fetch, github.vscode-pull-request-github/doSearch, github.vscode-pull-request-github/activePullRequest, github.vscode-pull-request-github/pullRequestStatusChecks, github.vscode-pull-request-github/openPullRequest]
agents: ["Explore", "Implement", "Review", "Spec", "Doc", "DocReview", "DevOps"]
user-invocable: true
disable-model-invocation: true
Expand Down
2 changes: 1 addition & 1 deletion .github/agents/Review.agent.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: "Use when: reviewing completed implementation against spec. Performs read-only code review for spec compliance, refactoring opportunities, and performance optimization."
model: GPT-5.4 (copilot)
tools: [vscode/memory, execute/getTerminalOutput, read, codegraphcontext/analyze_code_relationships, codegraphcontext/calculate_cyclomatic_complexity, codegraphcontext/find_code, codegraphcontext/find_dead_code, codegraphcontext/find_most_complex_functions, codegraphcontext/get_repository_stats, codegraphcontext/load_bundle, codegraphcontext/search_registry_bundles, codegraphcontext/visualize_graph_query, 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', search, web, github/get_file_contents, github/issue_read, github.vscode-pull-request-github/doSearch, github.vscode-pull-request-github/activePullRequest, todo]
tools: [vscode/memory, vscode/resolveMemoryFileUri, execute/getTerminalOutput, read, search, web, github/get_file_contents, github/issue_read, codegraphcontext/analyze_code_relationships, codegraphcontext/calculate_cyclomatic_complexity, codegraphcontext/find_code, codegraphcontext/find_dead_code, codegraphcontext/find_most_complex_functions, codegraphcontext/get_repository_stats, codegraphcontext/load_bundle, codegraphcontext/search_registry_bundles, codegraphcontext/visualize_graph_query, 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', todo, github.vscode-pull-request-github/doSearch, github.vscode-pull-request-github/activePullRequest]
agents: []
user-invocable: false
argument-hint: "Provide the spec/plan and list of changed files to review"
Expand Down
2 changes: 1 addition & 1 deletion .github/agents/Spec.agent.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: "Use when: updating or creating specification documents (file under Spec/). Writes clear specs targeting both human developers and AI agents."
model: GPT-5.4 (copilot)
tools: [vscode/memory, read, codegraphcontext/analyze_code_relationships, codegraphcontext/find_code, codegraphcontext/get_repository_stats, 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', edit, search, web, todo]
tools: [vscode/memory, vscode/resolveMemoryFileUri, read, edit, search, web, codegraphcontext/analyze_code_relationships, codegraphcontext/find_code, codegraphcontext/get_repository_stats, 'io.github.upstash/context7/*', 'microsoftdocs/mcp/*', todo]
agents: []
user-invocable: false
argument-hint: "Implement spec updates from the approved plan stored in /memories/session/plan.md"
Expand Down
99 changes: 96 additions & 3 deletions docs/Ioc/04_Field_Property_Method_Injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,107 @@ services.AddSingleton<global::MyNamespace.IMyService>((global::System.IServicePr
> - If no need to generate factory method (no field/property/method injection or decorator), will let `IServiceProvider` select constructor.
> - If factory method generation is needed (due to field/property/method injection or decorator), will use primary constructor, then the constructor with the most parameters.

## Async Method Injection

Use `[IocInject]` on a method that returns `Task` to perform async initialization after construction. The method is awaited after all synchronous injection steps.

> [!WARNING]
> `AsyncMethodInject` is **not** enabled by default. Add it to `SourceGenIocFeatures` in your project file:
>
> ```xml
> <PropertyGroup>
> <SourceGenIocFeatures>Register,Container,PropertyInject,MethodInject,AsyncMethodInject</SourceGenIocFeatures>
> </PropertyGroup>
> ```
>
> `AsyncMethodInject` requires `MethodInject` to be enabled. If `AsyncMethodInject` is enabled without `MethodInject`, the analyzer reports `SGIOC026`.

### Classification Rules

|Return Type|Classification|
|:---|:---|
|`void`|Synchronous method injection (`InjectionMemberType.Method`)|
|`Task` (non-generic)|Async method injection (`InjectionMemberType.AsyncMethod`)|
|`Task<T>`|Not supported — not a valid injection method return type|
|`ValueTask` / `ValueTask<T>`|Not supported — not a valid injection method return type|

### Injection Stage Order

The generator emits member injection in a fixed stage order. Source declaration order applies within each stage:

|Stage|Members|
|:----|:------|
|1|Properties|
|2|Fields|
|3|Synchronous methods (`void`)|
|4|Async methods (`Task`) — awaited last|

### Example

```csharp
using System.Threading.Tasks;

public interface IMyService;
public interface IDependency1;
public interface IDependency2;
public interface IDependency3;

[IocRegister<IMyService>(ServiceLifetime.Singleton)]
internal class MyService : IMyService
{
[IocInject]
public IDependency1 Dep1 { get; set; } = default!;

[IocInject]
public void SyncInit(IDependency2 dep2)
{
}

[IocInject]
public async Task AsyncInit(IDependency3 dep3)
{
await Task.CompletedTask;
}
}
```

<details>
<summary>Generated Code</summary>

```csharp
// <auto-generated/>
services.AddSingleton<global::System.Threading.Tasks.Task<global::MyNamespace.MyService>>((global::System.IServiceProvider sp) =>
{
async global::System.Threading.Tasks.Task<global::MyNamespace.MyService> Init()
{
var s0_p0 = sp.GetRequiredService<global::MyNamespace.IDependency1>(); // Stage 1: properties
var s0_m1 = sp.GetRequiredService<global::MyNamespace.IDependency2>();
var s0_m2 = sp.GetRequiredService<global::MyNamespace.IDependency3>();
var s0 = new global::MyNamespace.MyService() { Dep1 = s0_p0 };
s0.SyncInit(s0_m1); // Stage 3: sync methods
await s0.AsyncInit(s0_m2); // Stage 4: async methods
return s0;
}
return Init();
});
// Forwarding registration: Task<IMyService> → Task<MyService>
services.AddSingleton<global::System.Threading.Tasks.Task<global::MyNamespace.IMyService>>(async (global::System.IServiceProvider sp) => await sp.GetRequiredService<global::System.Threading.Tasks.Task<global::MyNamespace.MyService>>());
```

</details>

> [!NOTE]
> When a service has async inject methods, the registration type changes from `T` to `Task<T>`. Consumers that depend on this service should inject `Task<T>` and `await` the result. See [Wrapper Types — Task\<T\>](10_Wrapper.md#taskt) for consumer-side usage.

## Diagnostics

|ID|Severity|Description|
|:---|:---|:---|
|SGIOC007|Error|Invalid `[IocInject]` usage. The attribute cannot be applied to static members, non-accessible members (`private`, `protected`, `private protected` — but `protected internal` is accepted), properties without a setter or with an inaccessible setter, `readonly` fields, generic methods, non-ordinary methods (e.g., constructors, operators), or methods that do not return `void`.|
|SGIOC022|Warning|`[IocInject]` is ignored when the corresponding feature (`PropertyInject`, `FieldInject`, or `MethodInject`) is disabled in `SourceGenIocFeatures`.|
|SGIOC007|Error|Invalid `[IocInject]` usage. The attribute cannot be applied to static members, non-accessible members (`private`, `protected`, `private protected` — but `protected internal` is accepted), properties without a setter or with an inaccessible setter, `readonly` fields, generic methods, non-ordinary methods (e.g., constructors, operators), or methods with unsupported return types (only `void` and non-generic `Task` when `AsyncMethodInject` is enabled are accepted).|
|SGIOC022|Warning|`[IocInject]` is ignored when the corresponding feature (`PropertyInject`, `FieldInject`, `MethodInject`, or `AsyncMethodInject`) is disabled in `SourceGenIocFeatures`.|
|SGIOC026|Error|`AsyncMethodInject` feature requires `MethodInject` to be enabled.|
|SGIOC023|Error|An element in the `InjectMembers` array is not in a recognized format. Each element must be `nameof(member)` or `new object[] { nameof(member), key [, KeyType] }`.|
|SGIOC024|Error|A member specified via `InjectMembers` is not injectable (e.g., static, non-accessible members (`private`, `protected`, `private protected` — but `protected internal` is accepted), no setter or inaccessible setter, `readonly` field, generic method, non-ordinary method, or method that does not return `void`).|
|SGIOC024|Error|A member specified via `InjectMembers` is not injectable (e.g., static, non-accessible members (`private`, `protected`, `private protected` — but `protected internal` is accepted), no setter or inaccessible setter, `readonly` field, generic method, non-ordinary method, or method with unsupported return type).|

## InjectMembers: Attribute-Level Injection Without `[IocInject]`

Expand Down
Loading
Loading