局所化境界およびソースジェネレーター
PowerPortalsProは、ルートが最初のペイントされる前に必要なDataverseメタデータ由来の文字列をすべてプリフェッチするため、ユーザーはオンデマンドのローカリゼーションライブラリが通常生成する一瞬のフォールバックキーテキストのフラッシュを見ることはありません。この仕組みは三つの部分から成り立っています。セッションごとに1回読み込まれ、フレームワーク+アプリ文字列(tables.*/choices.*以外のすべて)をカバーする静的デフォルトバンドル、ビルドタイムのソースジェネレーター(各コンポーネントが必要なテーブルおよびビュートークンのコンポーネントマニフェストを出力)、そしてルートビューをラップし、ルートをレンダリングする前に並列リソースごとのバンドルフェッチを展開するランタイムLocalizationBoundaryコンポーネントです。
局所境界成分
LocalizationBoundaryRoutes.razorの中にAuthorizeRouteView(またはRouteView)を巻きつけます。すべてのナビゲーションで、現在のページタイプのソース生成のLocalizationManifest静的フィールドを読み込み、コンシューマーが設定した任意のBaselinePrefixesとトークンを合同し、結合トークンリストのIAsyncStringLocalizer.EnsurePrefixesLoadedAsyncを呼び出し、すべてのリソースごとのバンドルが取得されてキャッシュにマージされるまで子のレンダリングを保留します。取ってこい時は、半透明のオーバーレイとスピナーがビューポートを覆い、前のページの古びたテキストが見えないようにします。
ベースライントークン
ほとんどのアプリは BaselinePrefixes を設定する必要がなく、ソースジェネレーターがコンポーネントコードのルートごとのテーブルとビュートークンを自動的に検出します。アプリで知られている tables.{name} / views.{viewId} トークンで静的に検出できない場合にのみ使ってください(例:アカウントピッカーを常にレンダリングするレイアウトコンポーネントで、テーブルは暗黙的に表示されているもののジェネレーターがスキャンするマークアップには TableName="account" 属性が表示されない場合)。他のトークン形状はランタイムで静かにドロップされます。フレームワークのコンポーネント文字列は静的デフォルトバンドルで出荷されるため、ここで components.PowerPortalsPro.* や app.* 17を渡すのはノーオペレーションです。
配線
スターターテンプレートが LocalizationBoundary を設定してくれます。手動で統合する場合は、ルートビューをラップ Routes.razor 、このように配置してください:
// <LocalizationBoundary> ルートごとのコンテンツをラップし、保留します</LocalizationBoundary>
// 各ページの宣言されたバンドルが安定するまでレンダリングします。継承する
// 子孫の接頭辞宣言はuseLocalization()を呼び出し、
// 親の「prefixes」prop(<PowerPortalsProProvider>集合</PowerPortalsProProvider>)から
// Chromeが各ページに触れるアプリ全体のテーブル用です。
import { LocalizationBoundary } from '@powerportalspro/react-fluent';
import { Outlet } from 'react-router-dom';
function Layout() {
return (
<LocalizationBoundary>
<Outlet />
</LocalizationBoundary>
);
}@using PowerPortalsPro.Web.Blazor.FluentUI.Components
<Router AppAssembly="typeof(MyApp.RouteUrls).Assembly">
<Found Context="routeData">
<LocalizationBoundary RouteData="routeData">
<AuthorizeRouteView RouteData="routeData"
DefaultLayout="typeof(Layout.MainLayout)" />
</LocalizationBoundary>
</Found>
</Router>ソースジェネレーターとマニフェスト
PowerPortalsPro.Localization NuGetパッケージには、ビルド時にコンシュームプロジェクト内のすべての*.razorとコードをスキャンするRoslynソースジェネレーターがバンドルされています。各成分(継承ComponentBaseもの)に対して、public static readonly LocalizationKeyManifest LocalizationManifestフィールドを含む部分クラス拡張を放出します。マニフェストは実行時に要求するコンポーネント(およびレンダリングされるすべての静的に宣言された子)が要求する、tables.{name}およびviews.{viewId}トークンの推移集合を含みます。各トークンはリソースごとのバンドルURLに解決され、境界が最初のペイント前に並列にフェッチされます。tables.*/choices.*サブツリー(app.*、components.*)外の文字列は静的デフォルトバンドルから来ており、マニフェストから意図的に除外されます。
発生器が検出するもの
スキャナーは一般的なパターンを自動的に検出します — 注釈は不要です:
_localizer["tables.foo.…"]インデクサーアクセスは所有するtables.fooトークンに強制されます。_localizer["tables.foo.views.{guid}.…"]アクセスは、トークンviews.{guid}となります。@inject IStringLocalizer<T>Razorファイルでは、Localizerがどのフィールドに割り当てられているかをジェネレーターが追跡できるようにし、インデクサーのアクセスが正しくトークンを貢献できるようにします。GetPrefixedLocalizer("tables.foo")呼び出しのプレフィックスは対応するテーブルやビュートークンに強制的に組み込まれます。DefaultViewId/ViewId/ViewIdsグリッドコンポーネントの属性はトークンviews.{guid}を出力します。サーバーはリクエスト時にIDから所有テーブルを解決するため、マニフェストはそれを知る必要はありません。TableName="name"グリッド/レコードコンポーネントの属性はtables.{name}トークンを出力します。マッチングするテーブルごとのバンドルは、表示名、列メタデータ、テーブルのビュー(およびその列のオーバーライド)、そしてテーブルの列が参照するグローバルオプションセットの選択を返します。これらは、そのテーブルに必要なページが必要とするすべてのものを一度のフェッチで返します。- 直接子コンポーネントタグと属性値の
@typeof(SomeComponent)参照は、子のマニフェストを親の推移集合に引き込むため、動的コンポーネントをホストするページはトークンを事前に取得します。
マニフェストの検査
生成された LocalizationManifest フィールドは普通のパブリックスタティックで、任意の C# コードから検査したり、デバッガで展開したりできます。トークンは決定的にソートされているので、インクリメンタルビルドで生成されたファイルが切り捨てられません。
// Reactにはビルドタイムマニフェストはありません — ページごとのプレフィックスを宣言してください
// 命令的にuseLocalization()を通じて。フックはトークンをキューに送ります
// LocalizationBoundaryが読み取るのと同じデバウンスされたフェッチパイプラインです。
// そのため、それらを宣言したページはナビゲートしても生のキーが表示されません。
import { useLocalization } from '@powerportalspro/react';
function Dashboard() {
useLocalization([
'tables.opportunity',
'views.a1b2c3d4-e5f6-4789-abcd-112233445566',
]);
// ...ページの内容...
}// PowerPortalsPro.Localization.SourceGeneratorsによって生成
public partial class Dashboard
{
public static readonly LocalizationKeyManifest LocalizationManifest =
new LocalizationKeyManifest(
"tables.opportunity",
"views.a1b2c3d4-e5f6-4789-abcd-112233445566"
);
}オンデマンド・フォールバック
ジェネレーターがコンパイル時に解決できないもの、例えばランタイムの式から作られたキーや、プロジェクト参照境界を越える参照 new Guid(SomeQualifiedConst) などは、ローカライザーのオンデマンドパスに入ります。 tables.X.… キーや tables.X.views.Y.… キーのキャッシュミスは所有バンドルトークンに強制され、キューに入れられ、短時間デバウンスされ、バックグラウンドでフェッチされます。 LocalizationBoundary フェッチが完了すると子孫サブツリーを再マウントするため、古いフォールバックテキストは自動的に修正されます。他のキー形状(app.*、 components.*)のミスは無視されます。静的デフォルトバンドルはすでにチャンスを得たため、ミスはキーが存在しないことを意味します。
JSONで定義されたカスタムビュー
ローカリゼーションJSONファイル(例:app.en.json)で提供するカスタムビュー(通常はグリッド上のCustomViewDefinitionsでクライアント側で定義されたGUID付きのグリッドビュー)は、各ビューバンドルのエンドポイントによって自動的に取得されます。バンドルサービスはメタデータのみの savedquery マップではなくキーシェイプ(tables.{owningTable}.views.{viewId}.…)から所有テーブルを導き出すため、Dataverse に存在しないビューもマニフェストを通じて出荷されます。キーは大文字に気づかない方法でマッチングされます。"28299C6F-EBC0-4206-9E11-A373D4C9891F"(大文字でGUIDリテラルを書く自然な方法)のJSONファイルは、ソースジェネレーターがコードからviews.28299c6f-ebc0-4206-9e11-a373d4c9891fを出力すると正しく解決されます。
注記
Blazorコンポーネントをホストするプロジェクトの参考
PowerPortalsPro.Localization。このパッケージは、ランタイムタイプ(IStringLocalizer、IAsyncStringLocalizer、LocalizationKeyManifest、LocalizationBoundary)と、アナライザー資産としてのソースジェネレーターの両方を出荷しており、消費者は追加設定なしで次のビルドで自動的にマニフェストエミッションを受け取ります。
LocalizationBoundary クラス
パラメータ
名称 | 種類 | デフォルト | 概要 |
|---|---|---|---|
BaselinePrefixes | IEnumerable<string>? | ||
ChildContent | RenderFragment? | ||
RouteData | RouteData? |
BaselinePrefixesChildContentRouteData