Blazor: campos públicos readonly do RenderTreeFrame tornaram-se propriedades

No ASP.NET Core 3.0 e 3.1, o struct RenderTreeFrame expôs vários campos readonly public, incluindo FrameType, Sequencee outros. Em ASP.NET Core 5.0 RC1 e versões posteriores, todos os campos readonly public foram alterados para propriedades readonly public.

Essa alteração não afetará muitos desenvolvedores porque:

  • Qualquer aplicativo ou biblioteca que simplesmente use arquivos .razor (ou até mesmo chamadas manuais RenderTreeBuilder) para definir componentes não faria referência a esse tipo diretamente.
  • O tipo RenderTreeFrame em si é considerado um detalhe de implementação, não destinado ao uso fora da estrutura. O ASP.NET Core 3.0 e versões posteriores incluem um analisador que emite avisos do compilador se o tipo estiver sendo usado diretamente.
  • Mesmo que você faça referência a RenderTreeFrame diretamente, essa alteração é de ruptura binária, mas não de ruptura de origem. Ou seja, seu código-fonte existente será compilado e se comportará corretamente. Você só vai encontrar um problema se estiver compilando em uma estrutura do .NET Core 3.x e executando esses binários no .NET 5 ou em uma estrutura posterior.

Para discussão, confira o problema do GitHub dotnet/aspnetcore#25727.

Versão introduzida

5.0 RC1

Comportamento antigo

Os membros públicos RenderTreeFrame são definidos como campos. Por exemplo, renderTreeFrame.Sequence e renderTreeFrame.ElementName.

Novo comportamento

Os membros públicos em RenderTreeFrame são definidos como propriedades com os mesmos nomes de antes. Por exemplo, renderTreeFrame.Sequence e renderTreeFrame.ElementName.

Se o código pré-compilado mais antigo não tiver sido recompilado desde essa alteração, ele poderá gerar uma exceção semelhante a MissingFieldException: Field not found: "Microsoft.AspNetCore.Components.RenderTree.RenderTreeFrame.FrameType".

Motivo da alteração

Essa alteração foi necessária para implementar melhorias de desempenho de alto impacto na renderização de componente Razor no ASP.NET Core 5.0. Os mesmos níveis de segurança e encapsulamento são mantidos.

A maioria dos desenvolvedores do Blazor não é afetada por essa alteração. É mais provável que a alteração afete a biblioteca e os autores do pacote, mas apenas em casos raros. Especificamente, se você estiver desenvolvendo:

  • Um aplicativo, e estiver usando ASP.NET Core 3.x ou atualizando para 5.0 RC1 ou versão posterior, não será necessário alterar seu código. No entanto, se você depender de uma biblioteca que foi atualizada para considerar essa alteração, será necessário atualizar para uma versão mais recente dessa biblioteca.
  • Uma biblioteca, e quiser dar suporte apenas a ASP.NET Core 5.0 RC1 ou versão posterior, nenhuma ação é necessária. Basta garantir que o arquivo de projeto declare um valor <TargetFramework> de net5.0 ou uma versão posterior.
  • Uma biblioteca, e quiser dar suporte a ASP.NET Core 3.x e 5.0, determine se o código lê algum membro RenderTreeFrame. Por exemplo, avaliando someRenderTreeFrame.FrameType.
    • A maioria das bibliotecas não lê membros RenderTreeFrame, incluindo bibliotecas que contêm componentes .razor. Nesse caso, nenhuma ação é necessária.
    • No entanto, se a sua biblioteca fizer isso, você precisará ter vários destinos para dar suporte a ambos, netstandard2.1 e net5.0. Aplique as seguintes alterações em seu arquivo de projeto:
      • Substitua o elemento existente <TargetFramework> por <TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>.

      • Use uma referência condicional de pacoteMicrosoft.AspNetCore.Components para considerar as duas versões a que você deseja dar suporte. Por exemplo:

        <PackageReference Include="Microsoft.AspNetCore.Components" Version="3.0.0" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
        <PackageReference Include="Microsoft.AspNetCore.Components" Version="5.0.0-rc.1.*" Condition="'$(TargetFramework)' != 'netstandard2.0'" />
        

Para obter mais esclarecimentos, confira este diff showing how @jsakamoto already upgraded the Toolbelt.Blazor.HeadElement library.

APIs afetadas

Microsoft.AspNetCore.Components.RenderTree.RenderTreeFrame