Needlr Analyzers¶
Needlr includes optional Roslyn analyzers to help developers avoid common mistakes and ensure best practices.
Core Analyzers (NexusLabs.Needlr.Analyzers)¶
These analyzers are included with the NexusLabs.Needlr package.
| Rule ID | Severity | Description |
|---|---|---|
| NDLRCOR001 | Error | Reflection API used in AOT project |
| NDLRCOR002 | Warning | Plugin has constructor dependencies |
| NDLRCOR003 | Error | [DeferToContainer] attribute in generated code is ignored |
| NDLRCOR004 | Warning | Injectable type in global namespace may not be discovered |
| NDLRCOR005 | Warning | Lifetime mismatch: longer-lived service depends on shorter-lived service |
| NDLRCOR006 | Error | Circular dependency detected |
| NDLRCOR007 | Error | Intercept type must implement IMethodInterceptor |
| NDLRCOR008 | Warning | [Intercept] applied to class without interfaces |
| NDLRCOR009 | Info | Lazy |
| NDLRCOR010 | Info | IEnumerable |
| NDLRCOR011 | Info | [FromKeyedServices] keyed service usage tracking |
| NDLRCOR012 | Error | Disposable captive dependency |
| NDLRCOR015 | Error | [RegisterAs |
SignalR Analyzers(NexusLabs.Needlr.SignalR.Analyzers)¶
These analyzers are included with the NexusLabs.Needlr.SignalR package.
| Rule ID | Severity | Description |
|---|---|---|
| NDLRSIG001 | Warning | HubPath must be a constant expression |
| NDLRSIG002 | Warning | HubType must be a typeof expression |
| NDLRSIG003 | Error | IHubRegistrationPlugin implementation cannot use generated-constructor generation |
Logging Analyzers (NexusLabs.Needlr.Logging.Analyzers)¶
These analyzers are included with the NexusLabs.Needlr.Logging package and validate
[NeedlrLoggerMessage] usage.
| Rule ID | Severity | Description |
|---|---|---|
| NDLRLOG001 | Error | Method must be partial |
| NDLRLOG002 | Error | Method must return void |
| NDLRLOG003 | Error | Method must not be generic |
| NDLRLOG004 | Error | Containing type must be partial |
| NDLRLOG005 | Error | No accessible ILogger |
| NDLRLOG006 | Info | More than six non-exception parameters |
Generator Diagnostics (NexusLabs.Needlr.Generators)¶
These diagnostics are emitted by the source generator to detect configuration issues at compile time.
| Rule ID | Severity | Description |
|---|---|---|
| NDLRGEN001 | Error | Internal type in referenced assembly cannot be registered |
| NDLRGEN002 | Error | Referenced assembly has internal plugin types but no type registry |
| NDLRGEN003 | Warning | [GenerateFactory] all parameters are injectable |
| NDLRGEN004 | Warning | [GenerateFactory] no parameters are injectable |
| NDLRGEN005 | Error | [GenerateFactory |
| NDLRGEN006 | Error | [OpenDecoratorFor] type must be an open generic interface |
| NDLRGEN007 | Error | [OpenDecoratorFor] decorator must be an open generic class |
| NDLRGEN008 | Error | [OpenDecoratorFor] decorator must implement the interface |
| NDLRGEN014 | Error | [Options] Validator type has no validation method |
| NDLRGEN015 | Error | [Options] Validator type mismatch |
| NDLRGEN016 | Error | [Options] Validation method not found |
| NDLRGEN017 | Error | [Options] Validation method has wrong signature |
| NDLRGEN018 | Warning | [Options] Validator won't run (ValidateOnStart is false) |
| NDLRGEN019 | Warning | [Options] Validation method won't run (ValidateOnStart is false) |
| NDLRGEN020 | Error | [Options] is not compatible with Native AOT |
| NDLRGEN021 | Warning | [Options] Positional record must be partial |
| NDLRGEN022 | Error | Disposable captive dependency (uses inferred lifetimes) |
| NDLRGEN031 | Error | [Provider] on class requires partial modifier |
| NDLRGEN032 | Error | [Provider] interface has invalid member |
| NDLRGEN033 | Warning | [Provider] property uses concrete type |
| NDLRGEN034 | Error | [Provider] circular dependency detected |
| NDLRGEN035 | Error | [RegisterClosedOverImplementationsOf] source must be an open generic interface |
| NDLRGEN036 | Error | [RegisterClosedOverImplementationsOf] composition must be an open generic class |
| NDLRGEN037 | Error | [RegisterClosedOverImplementationsOf] composition must implement the As service type |
| NDLRGEN038 | Warning | [RegisterClosedOverImplementationsOf] discovered type argument violates composition constraints |
Generated Constructor Diagnostics (NexusLabs.Needlr.Generators)¶
These diagnostics are emitted by the GeneratedConstructorAnalyzer to validate [GenerateConstructor], [ConstructorGuard], [ConstructorIgnore], and [ConstructorGuardDefinition] usage.
| Rule ID | Severity | Description |
|---|---|---|
| NDLRGEN039 | Error | Generated-constructor type must be partial |
| NDLRGEN040 | Error | Generated-constructor type shape is unsupported (record or nested type) |
| NDLRGEN041 | Error | Generated-constructor conflicts with an explicit constructor |
| NDLRGEN042 | Error | Generated-constructor base type requires a parameterless constructor |
| NDLRGEN043 | Error | No eligible field for generated-constructor generation |
| NDLRGEN044 | Error | Generated-constructor parameter names collide |
| NDLRGEN045 | Warning | Constructor guard attribute has no effect |
| NDLRGEN046 | Error | Constructor guard attribute applied to an ineligible field |
| NDLRGEN047 | Error | Invalid constructor guard enum value |
| NDLRGEN048 | Error | Constructor guard incompatible with member type |
| NDLRGEN049 | Error | Custom constructor guard type is invalid |
| NDLRGEN050 | Error | Custom constructor guard method name is invalid |
| NDLRGEN051 | Error | Custom constructor guard method is invalid |
| NDLRGEN052 | Error | Custom constructor guard method is ambiguous |
| NDLRGEN053 | Error | [ConstructorGuardDefinition] target is invalid |
| NDLRGEN054 | Error | [ConstructorGuardDefinition] guard contract is unresolved |
| NDLRGEN055 | Error | Constructor guard alias usage argument is unsupported |
| NDLRGEN056 | Error | Custom constructor guard method is incompatible with forwarded alias arguments |
| NDLRGEN057 | Error | Record constructor-overload type must be partial |
| NDLRGEN058 | Error | Record constructor-overload type shape is unsupported |
| NDLRGEN059 | Error | Record constructor-overload property is unsupported |
| NDLRGEN060 | Error | Constructor guard property does not participate in an overload |
| NDLRGEN061 | Error | Record constructor overload conflicts with field-based generation |
| NDLRGEN062 | Error | Record constructor-overload signature collides |
| NDLRGEN063 | Info | Constructor can be generated by Needlr |
HttpClient Diagnostics (NexusLabs.Needlr.Generators)¶
These diagnostics are emitted by the HttpClientOptionsAnalyzer to catch misuse of the [HttpClientOptions] attribute at compile time.
| Rule ID | Severity | Description |
|---|---|---|
| NDLRHTTP001 | Error | [HttpClientOptions] target must implement INamedHttpClientOptions |
| NDLRHTTP002 | Error | HttpClient name sources conflict (attribute Name vs ClientName property) |
| NDLRHTTP003 | Error | ClientName property body is not a literal expression |
| NDLRHTTP004 | Error | Resolved HttpClient name is empty |
| NDLRHTTP005 | Error | Duplicate HttpClient name across the compilation |
| NDLRHTTP006 | Error | ClientName property has the wrong shape (must be instance string with getter) |
Diagnostic ID Naming Convention¶
Needlr uses a component-based naming convention for diagnostic IDs:
| Component | Prefix | Example |
|---|---|---|
| Core Analyzers | NDLRCOR |
NDLRCOR001 |
| SignalR Analyzers | NDLRSIG |
NDLRSIG001 |
| Logging Analyzers | NDLRLOG |
NDLRLOG001 |
| Source Generators | NDLRGEN |
NDLRGEN001 |
| HttpClient Analyzers | NDLRHTTP |
NDLRHTTP001 |
Suppressing Warnings¶
To suppress a specific analyzer warning, use pragma directives:
#pragma warning disable NDLRCOR001
// Code that triggers the warning
#pragma warning restore NDLRCOR001
Or suppress in your project file for the entire project:
Or configure severity in .editorconfig (recommended):
# .editorconfig
[*.cs]
# Disable a diagnostic
dotnet_diagnostic.NDLRCOR009.severity = none
# Promote to warning
dotnet_diagnostic.NDLRCOR010.severity = warning
# Promote to error
dotnet_diagnostic.NDLRCOR005.severity = error
NDLRGEN063 is advisory and defaults to Info. Repositories that require
Needlr-generated constructors can promote it without changing Needlr's defaults:
When the project also treats warnings as errors, that repository-specific promotion makes mechanically replaceable hand-written constructors build-breaking.
Resolution Validation Analyzers¶
NDLRCOR009, NDLRCOR010, and NDLRCOR011 are resolution validation analyzers that help catch potential issues with service resolution patterns.
These analyzers:
- Only activate when
[assembly: GenerateTypeRegistry]is present - Default to
Infoseverity (non-blocking) - Can be promoted to
WarningorErrorvia.editorconfig
| Analyzer | Purpose |
|---|---|
| NDLRCOR009 | Validates Lazy<T> references discoverable types |
| NDLRCOR010 | Validates IEnumerable<T> has implementations |
| NDLRCOR011 | Tracks [FromKeyedServices] keyed service usage |
To see which analyzers are active in your project, enable diagnostics output:
This generates AnalyzerStatus.md in your output directory showing all analyzers and their current severity.
Configuration¶
Analyzers are automatically enabled when you reference the Needlr packages. No additional configuration is required.
For AOT projects, ensure your project has the appropriate settings for the analyzers to detect AOT mode: