Gerador de Fronteira e Fonte de Localização

O PowerPortalsPro pré-busca todas as strings derivadas de metadados do Dataverse que uma rota precisará antes da primeira pintura da rota, para que os usuários nunca vejam o breve flash de texto de recurso que bibliotecas de localização sob demanda normalmente produzem. O mecanismo possui três metades — um bundle padrão estático carregado uma vez por sessão que cobre as strings framework + app (tudo fora tables.* de / choices.*), um gerador de fonte em tempo de construção que emite um manifesto por componente dos tokens de tabela e view que cada componente precisa, e um componente de runtime LocalizationBoundary que envolve a rota view e espalha coletas paralelas por bundle antes de permitir a renderização da rota.

O Componente Localização Fronteira

LocalizationBoundary envolve AuthorizeRouteView (ou RouteView) dentro Routes.razorde . Em cada navegação, ele lê o campo estático gerado LocalizationManifest pela fonte do tipo de página atual, une os tokens com qualquer BaselinePrefixes configuração do consumidor, chama IAsyncStringLocalizer.EnsurePrefixesLoadedAsync a lista combinada de tokens e adia a renderização dos filhos até que todos os pacotes por recurso sejam buscados e mesclados no cache. Enquanto o fetch está em voo, uma sobreposição translúcida com um spinner cobre a viewport, de modo que o texto velho da página anterior não fica visível.

Tokens de Referência

A maioria dos aplicativos nem precisa configurar BaselinePrefixes — o gerador de código-fonte detecta automaticamente a tabela por rota e visualiza os tokens do seu código de componente. Use-o apenas para tokens conhecidos tables.{name} views.{viewId} / apps que não são detectáveis estaticamente (por exemplo, um componente layout que sempre renderiza um seletor de conta, onde a tabela é implícita mas nenhum TableName="account" atributo aparece na marcação que o gerador escaneia). Outras formas de token são descartadas silenciosamente pelo runtime — as próprias strings de componentes do framework são incluídas no bundle padrão estático, então passar components.PowerPortalsPro.* ou app.* aqui é um no-op.

Ligando

O modelo inicial é LocalizationBoundary configurado para você. Se você está integrando manualmente, coloque-o dentro Routes.razor do wrapping da vista de rota, assim:

React
Blazor

O Gerador de Fonte e o Manifesto

O PowerPortalsPro.Localization pacote NuGet inclui um gerador de código-fonte Roslyn que escaneia todos *.razor os códigos e códigos do projeto que consume no momento da compilação. Para cada componente (qualquer coisa que ComponentBaseherde ), ele emite uma extensão de classe parcial que carrega um public static readonly LocalizationKeyManifest LocalizationManifest corpo. O manifesto contém o conjunto transitivo de tables.{name} e views.{viewId} tokens que o componente (e todo filho declarado estaticamente que ele renderiza) solicita em tempo de execução — cada token resolve para uma URL por pacote de recurso que a fronteira busca em paralelo antes da primeira pintura. Cadeias fora da tables.* subárvore / choices.* (app.*, components.*) vêm do fibrado padrão estático e são deliberadamente excluídas do manifesto.

O que o Gerador Detecta

O scanner capta automaticamente os padrões comuns — sem necessidade de anotações:

Inspecionando um Manifesto

O campo gerado LocalizationManifest é uma estática pública comum — você pode inspecioná-lo a partir de qualquer código C# ou expandi-lo no seu depurador. Os tokens são ordenados deterministicamente para que builds incrementais não descarreguem o arquivo gerado.

React
Blazor

Recurso Sob Demanda

Tudo o que o gerador não consegue resolver em tempo de compilação — chaves construídas a partir de expressões em tempo de execução, new Guid(SomeQualifiedConst) referências que cruzam o limite de referência do projeto, etc. — cai para o caminho sob demanda do localizador. Um erro de cache em uma tables.X.… chave ou tables.X.views.Y.… é forçado a entrar no token do pacote proprietário, colocado em fila, debouncado brevemente e buscado em segundo plano; LocalizationBoundary remonta a subárvore descendente assim que a busca termina, de modo que texto de reserva obsoleto é corrigido automaticamente. Erros em outras formas de chave (app.*, components.*) são ignorados — o bundle padrão estático já teve sua chance, então um erro significa que a chave realmente não existe.

Views Personalizados Definidos em JSON

Visões personalizadas que você envia em um arquivo JSON de localização (por exemplo app.en.json) — tipicamente visualizações em grade com um GUID escolhido a dedo, definido do lado do cliente via CustomViewDefinitions em grade — são captadas automaticamente pelo endpoint do pacote por visualização. O serviço de bundle deriva a tabela proprietária da forma de chave (tables.{owningTable}.views.{viewId}.…) em vez do mapa apenas savedquery de metadados, então uma visualização que não existe no Dataverse ainda é enviada pelo manifesto. As chaves são combinadas de forma insensível a maiúsculas e minúsculas: um arquivo JSON com "28299C6F-EBC0-4206-9E11-A373D4C9891F" (maiúsculas, a forma natural de criar um literal GUID) resolve corretamente quando o gerador fonte emite views.28299c6f-ebc0-4206-9e11-a373d4c9891f a partir do seu código.

Nota

Referência PowerPortalsPro.Localization de qualquer projeto que hospede componentes do Blazor. O pacote envia tanto os tipos de runtime (IStringLocalizer, IAsyncStringLocalizer, LocalizationKeyManifest, ) LocalizationBoundaryquanto o gerador de origem como um ativo de analisador — os consumidores recebem emissão manifesta automaticamente na próxima compilação, sem configuração adicional.

React Blazor

LocalizationBoundary Classe

Parâmetros

Nome
Tipo
Padrão
Descrição
BaselinePrefixesIEnumerable<string>?
Tabelas adicionais.* / escolhas.* prefixos/chaves para pré-buscar em cada navegação — normalmente linhas de base de metadados Dataverse que um aplicativo sabe que sempre precisa (por exemplo, tables.account se toda rota mostrar um seletor de conta). Outro prefixo As formas são descartadas pelo tempo de execução, já que o fibrado estático já as cobre. Prefixos já carregados são armazenados em cache por sessão e não são rebuscados.
ChildContentRenderFragment?
O conteúdo da rota será renderizado quando as localizações estiverem prontas. Normalmente um AutorizaVistaRota Autorizada.
RouteDataRouteData?
A rota atual é LocalizationBoundary.RouteData. Prefixo derivado é componentes. {RouteData.PageType.FullName}.
Nome: BaselinePrefixes
Tipo: IEnumerable<string>?
Descrição: Tabelas adicionais.* / escolhas.* prefixos/chaves para pré-buscar em cada navegação — normalmente linhas de base de metadados Dataverse que um aplicativo sabe que sempre precisa (por exemplo, tables.account se toda rota mostrar um seletor de conta). Outro prefixo As formas são descartadas pelo tempo de execução, já que o fibrado estático já as cobre. Prefixos já carregados são armazenados em cache por sessão e não são rebuscados.
Nome: ChildContent
Tipo: RenderFragment?
Descrição: O conteúdo da rota será renderizado quando as localizações estiverem prontas. Normalmente um AutorizaVistaRota Autorizada.
Nome: RouteData
Tipo: RouteData?
Descrição: A rota atual é LocalizationBoundary.RouteData. Prefixo derivado é componentes. {RouteData.PageType.FullName}.