-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Background
We've seen a few issue reports (e.g., #47824, #44974) where customers attempt to use the required
modifier on Blazor component parameter properties to ensure that the parameter will definitely have a value assigned to it.
Why this is a problem
This is not a supported pattern (and it likely never will be) because Blazor component parameters do not get assigned upon component instantiation. Instead, a ParameterView
object gets passed to the component's SetParametersAsync
method, which updates parameter property values accordingly. The required
modifier has no bearing on whether the parameter will have an entry in the ParameterView
. Furthermore, even for parameters that do have ParameterView
entries, their properties won't get values assigned until long after what the required
modifier is supposed to guarantee.
Currently, using the required
modifier in a Blazor component doesn't break anything, because any component extending ComponentBase
(or otherwise manually invoking ParameterView.SetParameterProperties()
) gets its properties set via refelction. But the required
modifier can mislead component authors into thinking that it will make the property "required", especially considering it makes nullability warnings go away.
Likewise, init
has no effect in any component whose parameters are set using ParameterView.SetParameterProperties()
, because reflection bypasses the "init-only" restriction.
If we implement #29550, then using required
or init
could cause compilation errors, since we won't be using reflection to bypass the restrictions that required
or init
impose. Therefore, for future-proofing reasons, it's in our best interest to ensure that customers avoid using these keywords on Blazor component properties.
Proposed solution
For all these reasons, we should consider implementing an analyzer that emits a warning whenever component properties use required
or init
. The analyzer message can suggest using the [EditorRequired]
attribute instead.