Web-Frontend-Framework: Eine Blazor-App für alle Plattformen

Seite 4: Nutzung von statischen Ressourcen

Inhaltsverzeichnis

Bei den statischen Ressourcen, die nicht im lokalen /wwwroot-Ordner des Blazor-Projekts, sondern im /wwwroot-Ordner einer referenzierten Razor Class Library liegen, muss der Parameter src der Skriptreferenz den Wert "_content" gefolgt von der Package-Id haben. Wurde diese nicht explizit festgelegt, ist der AssemblyName zu setzen. Wenn es kein Tag <AssemblyName> in der Projektdatei gibt, ist der Assemblyname dem Projektnamen voranzustellen:

<script src="/_content/<PackageID>/Datei.js"></script>

Abbildung 5 zeigt dies an zwei Beispielen:

  • JavaScript-Datei BlazorUtil.js, die von der Razor Class Library "ITVisions.Blazor" bereitgestellt wird
  • CSS-Datei style.css, die von der Razor Class Library "MLBlazorRCL" bereitgestellt wird

Beiden Dateien müssen in der Startdatei der nutzenden Blazor-Anwendung (hier: index.html, weil Blazor WebAssembly) per <script>- beziehungsweise <link>-Tag eingebunden werden.

Bild 5: Nutzung von statischen Webelementen aus einer Razor Class Library

(Bild: Dr. Holger Schwichtenberg)

Blazor Server, Blazor MAUI und Blazor Desktop laden die Razor Class Libraries erst bei Bedarf, also wenn eine Route aus der Razor Class Library verwendet oder eine Komponente aus der Razor Class Library eingebettet wird. Blazor WebAssembly lädt im Standard immer alle Assemblies beim Anwendungsstart vom Webserver, damit die Anwendung auch offline arbeiten kann. Dies können Entwickler ändern, indem sie Razor Class Library erst bei Bedarf nachladen. Damit ist es möglich, die Downloadlast beim Start der WebAssembly-Anwendung zu reduzieren. Diese Lazy Loading-Funktion gibt es seit .NET 5.0.

Bild 6: Erst beim Klick auf "Blazor-Beispiele außerhalb der MiracleList" wurde die SamplesRCL.dll per Lazy Loading nachgeladen, was beim Anwendungsstart die Ladelast um immerhin 116 KByte reduziert hat.

(Bild: Dr. Holger Schwichtenberg)

Die Standardprojektvorlage für Blazor WebAssembly-Anwendungen, die Microsoft ausliefert, enthält noch kein Lazy Loading. Um dies zu integrieren, sind folgende Schritte notwendig: Entwickler rufen ein neues Blazor-WebAssembly-Projekt (Target Framework .NET 5.0 oder höher) ins Leben, legen dann eine Razor Class Library an und verschieben die Datei Counter.razor aus dem Blazor WebAssembly-Projekt in die Razor Class Library. Zum Abschluss erhält in der Projektdatei (.csproj) des Blazor WebAssembly-Projekts der Name der nachzuladenden DLL die Dateiendung ".dll".

<ItemGroup>
<BlazorWebAssemblyLazyLoad Include="RCL.dll" />
</ItemGroup>

Im Blazor WebAssembly-Projekt muss die App.razor-Datei mit dem Inhalt des Listings 3 ersetzt werden. Die Klasse LazyAssemblyLoader und das Ereignis OnNavigateAsync() gibt es seit Blazor 5.0.

@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@inject LazyAssemblyLoader LazyAssemblyLoader

<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="lazyLoadedAssemblies" OnNavigateAsync="@OnNavigateAsync">
 <Navigating>
  <div>
   <p>Loading the requested page…</p>
  </div>
 </Navigating>
 <Found Context="routeData">
  <RouteView RouteData="@routeData" DefaultLayout="typeof(MainLayout)" />
 </Found>
 <NotFound>
  <LayoutView Layout="typeof(MainLayout)">
   <p>Sorry, there is nothing at this address.</p>
  </LayoutView>
 </NotFound>
</Router>

@code {
 private List<Assembly> lazyLoadedAssemblies =
    new List<Assembly>();

 private async Task OnNavigateAsync(NavigationContext args)
 {
  Console.WriteLine("OnNavigateAsync: " + args.Path);
  if (args.Path.EndsWith("counter"))
  {
   Console.WriteLine("Lazy Loading RCL.dll...");
   var assemblies = await LazyAssemblyLoader.LoadAssembliesAsync(new string[] { "RCL.dll" });
   lazyLoadedAssemblies.AddRange(assemblies);
  }
 }
}
}


Listing 3: App.razor mit Lazy Loading

Wer das Tag <BlazorWebAssemblyLazyLoad> in der Projektdatei des Blazor WebAssembly-Projekts vergisst, erhält die Fehlermeldung: "Unhandled exception rendering component: No assemblies have been marked as lazy-loadable. Use the 'BlazorWebAssemblyLazyLoad' item group in your project file to enable lazy loading an assembly."

Dieser Beitrag zeigt, wie Entwicklerinnen und Entwickler gemeinsame Razor Components und statische Webartefakte in mehrere Blazor-Anwendungen nutzen können, auch wenn diese auf verschiedenen Blazor-Arten basieren.

Allerdings verbleibt noch ein Thema, das immer dann zum Tragen kommt, wenn Entwickler Razor Components, die Datenbanken oder andere Ressourcen nutzen, zwischen Anwendungen in verschiedenen Blazor-Arten teilen will: Blazor Server, Blazor Desktop und Blazor MAUI können als 2-Tier-Anwendung mit direktem Datenbankzugriff umgesetzt werden. Blazor WebAssembly benötigt aber immer einen Application Server (3-Tier-Architektur) und auch bei den Mobilplattformen, die Blazor MAUI anspricht, ist ein direkter Datenbankzugriff mangels Treibern nicht immer möglich oder zumindest verpönt. In einem späteren Beitrag wird es daher darum gehen, wie Entwickler und Entwicklerinnen Razor Components so schreiben können, dass sie Daten sowohl direkt von einem Datenbankmanagementsystem als auch via Webservice lesen und schreiben können.

(fms)