Implementation Status¶
This project currently implements every MVP diagnostic ID from the starter document plus the starter's first future-rule expansion through HCR085.
Implemented Rules¶
| Rule | Analyzer | Code fix | Notes |
|---|---|---|---|
HCR001 |
Yes | Partial | High-confidence new HttpClient() detection in request-path types, Minimal API endpoint and route-group lambdas, loops, using ownership patterns, and top-level loop/using statements, with resolved custom HttpClient types, visible lookalike Minimal API receivers, and obvious xUnit/NUnit/MSTest test and lifecycle contexts skipped; code fix uses an existing method, local function, or primary-constructor IHttpClientFactory parameter when one is already in scope. |
HCR002 |
Yes | Yes | Static or singleton-owned manual field/property client initializers, direct assignments, and simple unreassigned local handoffs without PooledConnectionLifetime, including semantic IServiceCollection receiver validation and alias support, Microsoft DI registration-method ownership, resolved custom client filtering, reassignment-aware recognition for configured handler locals/fields/properties and local handler property assignments before client creation, namespace-aware qualified singleton registrations, and visible singleton factory registrations that construct implementations; code fix is limited to safe parameterless field initializers. |
HCR003 |
Yes | No | Factory-created clients cached through direct assignments, simple unreassigned local handoffs, or initializers into static HttpClient fields/properties or HttpClient fields/properties on known singleton services across the compilation, with semantic IServiceCollection receiver validation and alias support, Microsoft DI registration-method ownership, namespace-aware and resolved member IHttpClientFactory receiver validation, resolved CreateClient method ownership, qualified singleton registrations, unresolved provider-chain lookalike filtering, and visible singleton factory registrations that construct an implementation. |
HCR004 |
Yes | Guide | Compilation-wide registration model for typed clients injected into singletons, including nullable and common wrapped constructor parameters, namespace-aware constructor and factory resolution matching, lambda or anonymous singleton factory Microsoft DI service-provider resolutions, semantic validation of inferred and explicitly typed service-provider parameters including aliases, visible singleton factory registrations that construct an implementation, semantic IServiceCollection receiver validation with alias support, Microsoft DI registration-method ownership, typeof(...) singleton factory registrations, and namespace-aware matching for visible qualified singleton and typed-client type names. |
HCR005 |
Yes | Yes | Duplicate typed-client registrations across the compilation, including semantic IServiceCollection receiver validation with alias support, minimal-hosting Services receiver validation, semantic Microsoft DI registration-method ownership, resolved namespace-aware matching for qualified and unqualified type names, unresolved builder lookalike filtering, typeof(...) standalone registrations, and visible factory registrations that construct the typed-client implementation. |
HCR020 |
Yes | Guide | High-confidence request-scoped and known scoped service constructor dependencies, field captures, and property captures in direct or visibly inherited handler implementations, including semantic visible IServiceCollection receiver and alias validation, Microsoft DI registration-method ownership, scoped factory registrations that construct implementations, common deferred/collection wrappers, namespace-aware qualified request/scoped service names, nullable scoped service names, resolved custom request-type lookalike filtering, plus resolved or qualified handler-base lookalike filtering. |
HCR040 |
Yes | Yes | Duplicate standard resilience handlers and same-name custom resilience handlers with literal or constant names in one fluent AddHttpClient/IHttpClientBuilder chain, plus repeated standard handlers on the same visible unreassigned builder receiver, with AddHttpClient builder-return validation, resolved standard and named handler method ownership, and namespace-aware lookalike custom builders skipped. |
HCR041 |
Yes | Yes | Standard resilience handlers with visible unsafe typed-client or named-client calls across the compilation, including framework handler-extension, unsafe-method guard, Polly ShouldHandle, qualified retry-predicate HttpMethod ownership, safe-method equality, instance .Equals(...), and object.Equals(...) validation, boolean predicate composition, and single-return block lambdas, service-collection and minimal-hosting Services chain validation, unresolved builder lookalike filtering, unreassigned split IHttpClientBuilder locals, resolved namespace-aware typed-client matching, one- or two-generic typed-client registrations, constant named-client names, and unsafe HttpRequestMessage Send/SendAsync shapes with literal or constant custom methods including CONNECT; validates namespace-aware typed-client HttpClient and named-client factory receivers including this.-qualified fields/properties, follows named-client and request-message locals until reassignment, and skips disabled retries and safe-method-only retry predicates. |
HCR042 |
Yes | Yes | Standard hedging handlers with visible unsafe typed-client or named-client calls across the compilation, reusing the HCR041 unsafe-call index (typed/named clients, Send/SendAsync request shapes, builder locals, constants, lookalike filtering). Reports AddStandardHedgingHandler even when retry's DisableForUnsafeHttpMethods() is present, because that guard does not disable hedging. Suppresses only a visible safe-method-only Hedging.ShouldHandle predicate. The code fix replaces parameterless hedging with AddStandardResilienceHandler(options => options.Retry.DisableForUnsafeHttpMethods()) and withholds when hedging already has an options argument. |
HCR043 |
Yes | Yes | Custom AddResilienceHandler pipelines whose configure callback visibly calls framework AddRetry while the typed or named client sends an unsafe HTTP method, reusing the HCR041 unsafe-call index. Reports on the AddRetry token. Suppresses DisableForUnsafeHttpMethods(), safe-method-only ShouldHandle, and literal MaxRetryAttempts = 0. The code fix introduces an HttpRetryStrategyOptions local and calls DisableForUnsafeHttpMethods(); generic RetryStrategyOptions<T> and existing locals remain guidance-only. |
HCR060 |
Yes | Yes | Awaited and synchronous ResponseHeadersRead HTTP response ownership and disposal for local declarations and assignments, including HttpClient.Send(...), with resolved HttpClient receiver, method owner, HttpCompletionOption member, and response-return validation, using, same-block using-declaration transfer, reassignment-aware direct block-level Dispose() and finally disposal recognition, conditional-dispose filtering, task-local filtering, and returned response/wrapper constructor or initializer transfer heuristics; the code fix supports simple declarations and immediately adjacent uninitialized declaration-plus-assignment pairs. |
HCR061 |
Yes | Partial | Response content reads before visible status handling on awaited or synchronous HttpClient response locals initialized by declarations or standalone assignments, including synchronous Send(...), synchronous ReadAsStream(), common asynchronous HttpContent reads, ReadFromJsonAsync<T>(), and ReadFromJsonAsAsyncEnumerable<T>(), framework EnsureSuccessStatusCode(), IsSuccessStatusCode, and StatusCode recognition, reassignment-aware local tracking, returned-response filtering, and resolved custom-client, response-like type, or custom-extension filtering. The code fix inserts EnsureSuccessStatusCode() immediately after the response acquisition, including when content consumption is nested in later control flow. |
HCR062 |
Yes | Guide | Shared HttpClient.DefaultRequestHeaders mutation detection, including direct mutating methods, nested header collection mutations, property assignments, real HttpClient receiver validation, read-only access filtering, request-scoped HttpRequestMessage.Headers exclusions, and resolved custom-client filtering. |
HCR063 |
Yes | Partial | Sync-over-async detection for .Result, .Wait(), and .GetAwaiter().GetResult() on visible HttpClient async calls including JSON delete, read, and write extensions, visible task locals initialized or assigned from those calls before their latest write through cycle-safe alias chains, framework Task.ConfigureAwait(...) wrappers, and common HttpContent async operations including CopyToAsync(...), LoadIntoBufferAsync(...), and ReadFromJsonAsync<T>(), with awaited-call, cyclic/arbitrary-task, resolved custom-client, and custom-extension filtering. The code fix replaces .Result, .GetAwaiter().GetResult(), and parameterless .Wait() statements with await when the nearest containing function is already async; synchronous functions and .Wait(...) overloads remain guidance-only. |
HCR064 |
Yes | Yes | Cancellation-aware HTTP API detection for visible synchronous HttpClient.Send(...), HttpClient async calls including JSON delete, buffered/streaming reads, and JSON write extensions, and common synchronous or asynchronous HttpContent reads, including ReadAsStream(), ReadFromJsonAsync<T>(), and ReadFromJsonAsAsyncEnumerable<T>(), that omit an available CancellationToken or pass CancellationToken.None or a default token; covers method/lambda parameters, prior-local tokens, visible CancellationTokenSource values, token overload validation, existing usable-token recognition, no-visible-token filtering, and resolved custom-client or custom-extension filtering. The code fix passes the sole visible token or token-source Token, replaces non-canceling token arguments, or offers a distinct action for each in-scope cancellation boundary. |
HCR080 |
Yes | Guide | Obvious unbounded Task.WhenAll HTTP fan-out with inline or visible local LINQ Select(...) task sequences sourced from the latest initializer or standalone assignment, including response-body helpers and framework JSON delete/read/write extensions, BCL Task, and resolved HttpClient receiver and method-owner validation; skips symbol-equivalent or visibly declared same-receiver SemaphoreSlim gates, bounded Parallel.ForEachAsync, nested task-sequence writes, reassignment-aware local/member clients backed by real framework SocketsHttpHandler.MaxConnectionsPerServer or HttpClientHandler.MaxConnectionsPerServer evidence including this.-qualified members and shared handler fields, and resolved custom clients, lookalike async methods, custom HTTP/JSON extensions, custom Select(...) methods, or lookalike handler limit properties. |
HCR081 |
Yes | Partial | HTTP stream ownership detection for streams materialized from HttpClient.GetStreamAsync(...), HttpContent.ReadAsStreamAsync(...), or synchronous HttpContent.ReadAsStream(), including local declarations and assignments, direct dispose or dispose-async recognition through visible reassignment-aware local alias chains populated by initializers or top-level standalone assignments, using statement/declaration ownership, alias-aware return and returned-wrapper ownership transfer, reassignment checks for returned owner locals, and resolved custom-client or custom-extension filtering. The code fix converts simple declarations to using declarations and merges an immediately adjacent uninitialized declaration plus assignment; non-adjacent or nested assignments remain guidance-only. |
HCR082 |
Yes | Guide | Per-request Polly.ResiliencePipelineBuilder.Build() detection inside obvious request paths, including controller/service-style type suffixes and Minimal API endpoint lambdas, visible builder-local tracking, fluent builder chains, static-field/startup/test-context filtering, resolved custom-builder filtering, and resolved build-method ownership validation. |
HCR083 |
Yes | Guide | Typed-client relative URL detection for registered AddHttpClient<T>() and AddHttpClient<TService,TImplementation>() clients without visible BaseAddress configuration, including inline or visible reassignment-aware local string and semantic System.Uri arguments for common direct HTTP and framework buffered/streaming System.Net.Http.Json calls, plus inline or visible local HttpRequestMessage instances passed to Send or SendAsync, string and semantic System.Uri request constructor arguments, semantic RequestUri object-initializer and visible property-assignment inspection, split declaration/assignment tracking with reassignment filtering, semantic IServiceCollection receiver validation with alias support, Microsoft DI AddHttpClient ownership, direct AddHttpClient(..., client => client.BaseAddress = ...), framework-owned chained ConfigureHttpClient(...), and unreassigned split builder-local filtering, resolved configuration-extension, JSON extension, BaseAddress property, request/client receiver validation, absolute URL filtering, and custom-client filtering. |
HCR084 |
Yes | Guide | Named-client literal duplication detection between visible string-literal, inline compile-time concatenation/conditional/interpolation, or reassignment-aware local AddHttpClient(...) registrations and matching IHttpClientFactory.CreateClient(...) use sites, including split direct assignments, namespace-aware service-collection and factory receiver validation, IHttpClientBuilder registration-result validation, resolved CreateClient method ownership, shared-constant, runtime-computed, and ambiguous-mutation filtering, and custom factory or registration lookalike filtering. |
HCR085 |
Yes | Guide | Compilation-wide detection of different AddHttpClient<TService,TImplementation>() implementations that share the same resolved service type and therefore the same implicit named-client configuration, including cross-file and minimal-hosting registrations, configured and parameterless overloads, deterministic later-registration reporting, and first-registration additional locations; explicit names, repeated implementations, one-generic registrations, unresolved symbols, and custom extension lookalikes are skipped. |
Current Limitations¶
- Cross-file DI graph analysis is intentionally lightweight; it matches direct
IServiceCollection-shaped registration calls across syntax trees but does not expand arbitrary custom wrapper semantics beyond visible calls. HCR041models visible typed-client and named-client call sites across syntax trees, including string literals and compile-time constants for named clients and customHttpMethodstring names, but it does not trace values through mutable variables or configuration.HCR042uses the same evidence bar asHCR041for unsafe calls, and does not infer hedging from custom wrappers or configuration-driven method names.HCR043uses the same evidence bar asHCR041for unsafe calls, and does not follow configure callbacks that are method groups on another type, static pipelines not wired throughAddResilienceHandler, or configuration-driven method names.HCR060uses local ownership heuristics rather than full control-flow analysis.HCR080is intentionally suggestion-level and heuristic.HCR081tracks local stream ownership heuristically rather than full interprocedural ownership flow.HCR082intentionally limits request-path evidence to visible type names and Minimal API shapes; it does not infer arbitrary framework dispatch conventions.HCR083follows visible typed-client registrations and simple string URL constants; it does not evaluate configuration-driven base addresses.HCR084intentionally reports duplicated string literals, not constant-backed names or configuration-provided names.HCR085intentionally treats every explicit client name as deliberate intent and does not infer naming semantics through custom registration wrappers.