You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In ASP.NET Core 3.0 Preview 8 release we added a productivity feature in Blazor to automatically generate backing fields for elements that utilized the @ref attribute. Unfortunately, we missed a critical design flaw which prevents this from working end-to-end.
Trying to invoke build on a project with a Counter component that looked like the following would result in a build error:
<Counter@ref="myCounter" />
@code{// This will not compile because there will be no backing field for myCounterprivatereadonlyint_incrementingBy=myCounter.IncrementAmount;
}
Given that we're so close to a 3.0 release, we are going to cut this feature from 3.0. We will think about viable solutions to this in future releases, if we can find one, we may consider it then.
The problem deep dive
To summarize the problem effectively, I need to describe how the Razor compilation process works. It's a two-phase process:
Discovery: All the components and directive attributes are discovered. Razor does this by generating a skeleton of each component file and then introspecting on their structure, we call these files declarations. Basically, any content in your Razor file that isn't a directive or inside of a directive block @code is thrown out to avoid compilation errors during this phase.
Compiling: The actual Razor file compilation where it uses the inputs resolved in phase 1. This phase utilizes all of discovered components to properly parse HTML elements that look like components and uses all of the discovered directive attributes to properly parse those elements corresponding attributes that look like directive attributes.
The process is broken into two phases to enable Components to be written in Razor yet also impact other Razor files in the project. This is why you can write a Counter.razor file and still recursively use it in the same Counter.razor file.
The core problem is that during the discovery phase the Razor compiler has no awareness of the available components or directive attributes (it hasn't discovered them yet). This means, the @ref attribute and other component's existence is not available in this phase. This introduces a problem because a user may have written code in their @code block that references the supposed backing field generated from @ref; however, during discovery we didn't know about @ref so no backing field was generated. This results in Razor skeleton file that can't be compiled or introspected on (C# errors). We considered working around this limitation by hard coding @ref to not require the first phase but quickly found that would not work either because if a user writes <Counter @ref="myCounter" /> We need to generate a proper type name for the auto-generated backing field (private Counter myCounter;) which isn't reliably available because during the discovery phase we haven't yet discovered anything (it's not till phase 2 that we know of Counter).
Workaround
In 3.0.0-preview8 in order to utilize the @ref attribute you must do:
What's happening
In ASP.NET Core 3.0 Preview 8 release we added a productivity feature in Blazor to automatically generate backing fields for elements that utilized the
@ref
attribute. Unfortunately, we missed a critical design flaw which prevents this from working end-to-end.Trying to invoke build on a project with a
Counter
component that looked like the following would result in a build error:Given that we're so close to a 3.0 release, we are going to cut this feature from 3.0. We will think about viable solutions to this in future releases, if we can find one, we may consider it then.
The problem deep dive
To summarize the problem effectively, I need to describe how the Razor compilation process works. It's a two-phase process:
@code
is thrown out to avoid compilation errors during this phase.The process is broken into two phases to enable Components to be written in Razor yet also impact other Razor files in the project. This is why you can write a
Counter.razor
file and still recursively use it in the sameCounter.razor
file.The core problem is that during the
discovery
phase the Razor compiler has no awareness of the available components or directive attributes (it hasn't discovered them yet). This means, the@ref
attribute and other component's existence is not available in this phase. This introduces a problem because a user may have written code in their@code
block that references the supposed backing field generated from@ref
; however, during discovery we didn't know about@ref
so no backing field was generated. This results in Razor skeleton file that can't be compiled or introspected on (C# errors). We considered working around this limitation by hard coding@ref
to not require the first phase but quickly found that would not work either because if a user writes<Counter @ref="myCounter" />
We need to generate a proper type name for the auto-generated backing field (private Counter myCounter;
) which isn't reliably available because during the discovery phase we haven't yet discovered anything (it's not till phase 2 that we know ofCounter
).Workaround
In 3.0.0-preview8 in order to utilize the
@ref
attribute you must do:Once 3.0.0-preview9 and up ships you will be able to use the older syntax such as:
The text was updated successfully, but these errors were encountered: