Skip to content

Blazor Analyzer/code fix: Inject properties should be declared non-nullable and with null forgiving operator #11894

@omccully

Description

@omccully

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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions