Analyzer
SF0007
Flags supporting files whose inbound reference count exceeds the most referenced primary-path file, signaling that the scaffolding has become easier to see than the real flow.
Diagnostic contract
If more code points at the support structure than at the actual business path, the product behavior is no longer the dominant story in the system.
A non-primary-path source file has more inbound references than the highest referenced primary-path file.
File {0} has {1} inbound references, exceeding the highest primary-path file count of {2}
/analyzers/sf0007/
When it fires
These are the concrete cases to look for in code review and IDE diagnostics.
- The analyzer first identifies primary-path files by [PrimaryPath] annotation; if none exist, it falls back to Controllers, Endpoints, Handlers, and Pages folders.
- It counts inbound type references per source file and compares non-primary-path files to the strongest primary-path reference count.
- It reports only when a supporting file exceeds that primary-path ceiling.
Bad / better example
Use these examples to explain the rule, not just silence it.
Before
public sealed class PolicyRegistry { }
public sealed class CheckoutHandler(PolicyRegistry registry) { }
public sealed class RefundHandler(PolicyRegistry registry) { }
public sealed class RenewalHandler(PolicyRegistry registry) { }
public sealed class TrialConversionHandler(PolicyRegistry registry) { } The support object becomes the real center of gravity while the business handlers look secondary.
After
using SimplicityTools.Metrics;
[PrimaryPath]
public sealed class CheckoutHandler(OrderRepository orders, PaymentGateway gateway)
{
public Task<Result> HandleAsync(Request request) => gateway.AuthorizeAsync(request.ToOrder());
}
public sealed class RetryPolicy
{
public static bool ShouldRetry(int attempts) => attempts < 3;
} The real path is explicit and direct, while support code stays obviously supportive.
Code fix
There is no automatic code fix for this rule today. Treat it as a prompt to simplify deliberately.
- Add [PrimaryPath] annotations if the conventions are not enough to tell the tooling what really matters.
- Move orchestration back into primary-path handlers instead of centralizing every decision in support registries or framework glue.
- Treat this as a whole-flow signal, not as a demand to eliminate every shared utility.
Source and follow-up links
Use these links when you need to validate behavior against the source or connect the docs back to project tracking.
Analyzer implementation
NonPrimaryPathOverReferencedAnalyzer.cs
TrackingIssue #55
Documentation tracker for the analyzer pages and related integration guidance.
FilterPrimaryPathFirst
This rule is the sharpest analyzer expression of the PrimaryPathFirst filter.
Guidecsproj reference
Install the analyzer package and use [PrimaryPath] explicitly when conventions are not enough.