-
Notifications
You must be signed in to change notification settings - Fork 219
Description
Background and Motivation
This is typically how we declare Inject services with Blazor (private or public is a separate question, but I'll assume public for all of my examples):
[Inject]
public IMyService MyService { get; set; } = default!;Any other variation of this makes no sense.
Someone might try to do something like this as a first attempt (you see this in a lot of tutorials where people are not taking into account the nullability checking):
[Inject]
public IMyService MyService { get; set; }Then it gives them a null warning, so they may not understand how to correctly declare it to avoid the warning. Someone new may do something like this:
[Inject]
public IMyService? MyService { get; set; }Which compiles with no warnings, but then they must check if it's null anywhere they use it.
The methods to register services, such as AddSingleton do not accept null values, so having it be nullable would never make sense.
Proposed Analyzer
Analyzer Behavior and Message
My suggestion is to make an analyzer to ensure all properties with InjectAttribute (when in a nullable context):
- are declared as non-nullable
- have the null-forgiving operator (
= default!or= null!)
These kinds of context-specific analyzers could be helpful for people who struggle with adopting best practices when it comes to nullability.
Proposed message: "Inject property '{0}' should be declared as non-nullable and have the null forgiveness operator"
There can be a code fix for correcting this as well.
Category
- Design
- Documentation
- Globalization
- Interoperability
- Maintainability
- Naming
- Performance
- Reliability
- Security
- Style
- Usage
Severity Level
- Error
- Warning
- Info
- Hidden
Usage Scenarios
Bad:
[Inject]
public IMyService? MyService { get; set; }Bad (there will also be the regular null warning in this case, but having this warning as well would be helpful for giving people better information on the correct fix):
[Inject]
public IMyService MyService { get; set; }Good:
[Inject]
public IMyService MyService { get; set; } = default!;Risks
For code cleanup purposes, I don't see any reason why the Inject properties should be declared any differently.