Lazy Loading von Assemblys in ASP.NET Core Blazor WebAssembly

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Die Startleistung einer Blazor WebAssembly-App kann verbessert werden, indem das Laden einiger durch Entwickler erstellte App-Assemblys verzögert wird, bis die Assemblys benötigt werden. Dies wird als Lazy Loading bezeichnet.

In den ersten Abschnitten dieses Artikels wird die App-Konfiguration behandelt. Eine funktionierende Demo finden Sie im Abschnitt Vollständiges Beispiel am Ende dieses Artikels.

Dieser Artikel gilt nur für Blazor WebAssembly-Apps. Das verzögerte Laden von Assemblys stellt keinen Vorteil für serverseitige Apps dar, da vom Server gerenderte Apps keine Assemblys auf den Client herunterladen.

Lazy Loading sollte nicht für Kern-Assemblys in Runtime verwendet werden, die vielleicht zum Veröffentlichen zugeschnitten wurden und ggf. nicht verfügbar sind, wenn die Apps geladen werden.

Dateierweiterungsplatzhalter ({FILE EXTENSION}) für Assemblydateien

Assemblydateien verwenden das Webcil-Verpackungsformat für .NET-Assemblys mit der Dateierweiterung .wasm.

Im gesamten Artikel steht der Platzhalter {FILE EXTENSION} für „wasm“.

Assemblydateien basieren auf Dynamic-Link Libraries (DLLs) mit der Dateierweiterung .dll.

Im gesamten Artikel steht der Platzhalter {FILE EXTENSION} für „dll“.

Projektdateikonfiguration

Markieren Sie Assemblys in der Projektdatei der App (.csproj) mithilfe des BlazorWebAssemblyLazyLoad-Elements für Lazy Loading. Verwenden Sie den Assemblynamen mit der Dateierweiterung. Das Blazor-Framework verhindert, dass die Assembly beim App-Start geladen wird.

<ItemGroup>
  <BlazorWebAssemblyLazyLoad Include="{ASSEMBLY NAME}.{FILE EXTENSION}" />
</ItemGroup>

Der Platzhalter {ASSEMBLY NAME} steht für den Namen der Assembly, und der Platzhalter {FILE EXTENSION} ist die Dateierweiterung. Die Dateierweiterung ist erforderlich.

Fügen Sie für jede Assembly ein BlazorWebAssemblyLazyLoad-Element ein. Wenn eine Assembly Abhängigkeiten aufweist, müssen Sie einen BlazorWebAssemblyLazyLoad-Eintrag für jede Abhängigkeit einfügen.

Router-Komponentenkonfiguration

Das Blazor-Framework registriert automatisch einen Singleton-Dienst für das verzögerte Laden von Assemblys in clientseitigen Blazor WebAssembly-Apps, LazyAssemblyLoader. Die LazyAssemblyLoader.LoadAssembliesAsync-Methode:

  • Verwendet JS Interop zum Abrufen von Assemblys über einen Netzwerkaufruf.
  • Lädt Assemblys in die Laufzeit, die für WebAssembly im Browser ausgeführt werden.

Hinweis

Anleitungen für gehosteteBlazor WebAssemblyLösungen finden Sie im Abschnitt Verzögertes Laden von Assemblys in einer gehosteten Blazor WebAssembly-Lösung.

Die Router-Komponente von Blazor bestimmt die Assemblys, die Blazor nach routingfähigen Komponenten durchsucht, und ist auch für das Rendern der Komponente für die Navigationsroute des Benutzers zuständig. Die OnNavigateAsync-Methode der Router-Komponente wird in Verbindung mit Lazy Loading verwendet, um die richtigen Assemblys für Endpunkte zu laden, die ein Benutzer anfordert.

Die Logik wird in OnNavigateAsync implementiert, um die Assemblys zu bestimmen, die mit LazyAssemblyLoader geladen werden sollen. Optionen zum Strukturieren der Logik sind u. a.:

  • Bedingte Überprüfungen innerhalb der OnNavigateAsync-Methode.
  • Eine Nachschlagetabelle, in der Routen Assemblynamen zugeordnet werden, die entweder in die Komponente eingefügt oder innerhalb des @code-Blocks implementiert werden.

Im folgenden Beispiel:

  • Der Namespace für Microsoft.AspNetCore.Components.WebAssembly.Services wird angegeben.
  • Der LazyAssemblyLoader-Dienst wird eingefügt (AssemblyLoader).
  • Der {PATH}-Platzhalter ist der Pfad, in den die Liste der Assemblys geladen werden soll. Im Beispiel wird eine bedingte Überprüfung für einen einzelnen Pfad verwendet, der einen einzelnen Satz von Assemblys lädt.
  • Der Platzhalter {LIST OF ASSEMBLIES} steht für die durch Trennzeichen getrennte Liste von Zeichenfolgen für Assemblydateinamen, einschließlich ihrer Dateierweiterungen (z. B. "Assembly1.{FILE EXTENSION}", "Assembly2.{FILE EXTENSION}").

App.razor:

@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject LazyAssemblyLoader AssemblyLoader
@inject ILogger<App> Logger

<Router AppAssembly="typeof(App).Assembly" 
    OnNavigateAsync="OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
           {
               if (args.Path == "{PATH}")
               {
                   var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                       new[] { {LIST OF ASSEMBLIES} });
               }
           }
           catch (Exception ex)
           {
               Logger.LogError("Error: {Message}", ex.Message);
           }
    }
}
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject LazyAssemblyLoader AssemblyLoader
@inject ILogger<App> Logger

<Router AppAssembly="typeof(Program).Assembly" 
    OnNavigateAsync="OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
           {
               if (args.Path == "{PATH}")
               {
                   var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                       new[] { {LIST OF ASSEMBLIES} });
               }
           }
           catch (Exception ex)
           {
               Logger.LogError("Error: {Message}", ex.Message);
           }
    }
}

Hinweis

Im obigen Beispiel wird der Inhalt des Razor-Markups der Router-Komponente nicht angezeigt (...). Eine Demo mit vollständigem Code finden Sie im Abschnitt Vollständiges Beispiel dieses Artikels.

Hinweis

Seit der Veröffentlichung von ASP.NET Core 5.0.1 und allen weiteren 5.x-Releases enthält die Router-Komponente den PreferExactMatches-Parameter, der auf @true festgelegt ist. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core 3.1 zu 5.0.

Assemblys, die routingfähige Komponenten enthalten

Wenn die Liste der Assemblys routingfähige Komponenten enthält, wird die Assemblyliste für einen bestimmten Pfad an die AdditionalAssemblies-Auflistung der Router-Komponente übergeben.

Im folgenden Beispiel:

  • Die List<Assembly> in lazyLoadedAssemblies übergibt die Assemblyliste an AdditionalAssemblies. Das Framework durchsucht die Assemblys nach Routen und aktualisiert die Routenauflistung, wenn neue Routen gefunden werden. Um auf den Assembly-Typ zuzugreifen, wird der Namespace für System.Reflection am Anfang der Datei App.razor eingefügt.
  • Der {PATH}-Platzhalter ist der Pfad, in den die Liste der Assemblys geladen werden soll. Im Beispiel wird eine bedingte Überprüfung für einen einzelnen Pfad verwendet, der einen einzelnen Satz von Assemblys lädt.
  • Der Platzhalter {LIST OF ASSEMBLIES} steht für die durch Trennzeichen getrennte Liste von Zeichenfolgen für Assemblydateinamen, einschließlich ihrer Dateierweiterungen (z. B. "Assembly1.{FILE EXTENSION}", "Assembly2.{FILE EXTENSION}").

App.razor:

@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject ILogger<App> Logger
@inject LazyAssemblyLoader AssemblyLoader

<Router AppAssembly="typeof(App).Assembly" 
    AdditionalAssemblies="lazyLoadedAssemblies" 
    OnNavigateAsync="OnNavigateAsync">
    ...
</Router>

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

    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
           {
               if (args.Path == "{PATH}")
               {
                   var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                       new[] { {LIST OF ASSEMBLIES} });
                   lazyLoadedAssemblies.AddRange(assemblies);
               }
           }
           catch (Exception ex)
           {
               Logger.LogError("Error: {Message}", ex.Message);
           }
    }
}
@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject ILogger<App> Logger
@inject LazyAssemblyLoader AssemblyLoader

<Router AppAssembly="typeof(Program).Assembly" 
    AdditionalAssemblies="lazyLoadedAssemblies" 
    OnNavigateAsync="OnNavigateAsync">
    ...
</Router>

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

    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
           {
               if (args.Path == "{PATH}")
               {
                   var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                       new[] { {LIST OF ASSEMBLIES} });
                   lazyLoadedAssemblies.AddRange(assemblies);
               }
           }
           catch (Exception ex)
           {
               Logger.LogError("Error: {Message}", ex.Message);
           }
    }
}

Hinweis

Im obigen Beispiel wird der Inhalt des Razor-Markups der Router-Komponente nicht angezeigt (...). Eine Demo mit vollständigem Code finden Sie im Abschnitt Vollständiges Beispiel dieses Artikels.

Hinweis

Seit der Veröffentlichung von ASP.NET Core 5.0.1 und allen weiteren 5.x-Releases enthält die Router-Komponente den PreferExactMatches-Parameter, der auf @true festgelegt ist. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core 3.1 zu 5.0.

Weitere Informationen finden Sie unter ASP.NET Core: Routing und Navigation in Blazor.

Benutzerinteraktion mit <Navigating>-Inhalt

Beim Laden von Assemblys, was mehrere Sekunden dauern kann, kann die Router-Komponente dem Benutzer mit der Navigating-Eigenschaft des Routers anzeigen, dass ein Seitenübergang stattfindet.

Weitere Informationen finden Sie unter ASP.NET Core: Routing und Navigation in Blazor.

Verarbeiten von Abbrüchen in OnNavigateAsync

Das NavigationContext-Objekt, das an den OnNavigateAsync-Rückruf übergeben wird, enthält ein CancellationToken, das beim Auftreten eines neuen Navigationsereignisses festgelegt wird. Der OnNavigateAsync-Rückruf muss ausgelöst werden, wenn das Abbruchtoken festgelegt wird, um zu vermeiden, dass der OnNavigateAsync-Rückruf für eine veraltete Navigation weiterhin ausgeführt wird.

Weitere Informationen finden Sie unter ASP.NET Core: Routing und Navigation in Blazor.

OnNavigateAsync-Ereignisse und umbenannte Assemblydateien

Das Ressourcenladeprogramm benötigt die Assemblynamen, die in der blazor.boot.json-Datei definiert sind. Wenn Assemblys umbenannt werden, stimmen die Assemblynamen, die in OnNavigateAsync-Rückrufen verwendet werden, und die Assemblynamen in der blazor.boot.json-Datei nicht mehr überein.

So beheben Sie dies:

  • Überprüfen Sie, ob die App in der Production-Umgebung ausgeführt wird, wenn Sie bestimmen, welche Assemblynamen verwendet werden sollen.
  • Speichern Sie die umbenannten Assemblynamen in einer eigenen Datei, und lesen Sie die Namen aus dieser Datei, um zu bestimmen, welche Assemblynamen im LazyAssemblyLoader-Dienst und dem OnNavigateAsync-Rückruf verwendet werden sollen.

Verzögertes Laden von Assemblys in einer gehosteten Blazor WebAssembly-Projektmappe

Die Lazy Loading-Implementierung des Frameworks unterstützt Lazy Loading mit Prerendering in einer gehosteten Blazor WebAssemblyLösung. Während des PreRenderings werden alle Assemblys (einschließlich der für Lazy Loading markierten Assemblys) als geladen angenommen. Registrieren Sie den LazyAssemblyLoader-Dienst manuell im Server -Projekt.

Fügen Sie am Anfang der Program.cs-Datei des Server -Projekts den Namespace für Microsoft.AspNetCore.Components.WebAssembly.Services hinzu:

using Microsoft.AspNetCore.Components.WebAssembly.Services;

Registrieren Sie den Dienst in der Program.cs-Datei des Server -Projekts:

builder.Services.AddScoped<LazyAssemblyLoader>();

Fügen Sie am Anfang der Startup.cs-Datei des Server -Projekts den Namespace für Microsoft.AspNetCore.Components.WebAssembly.Services hinzu:

using Microsoft.AspNetCore.Components.WebAssembly.Services;

Registrieren Sie den Dienst in Startup.ConfigureServices (Startup.cs) des Server-Projekts:

services.AddScoped<LazyAssemblyLoader>();

Vollständiges Beispiel

Die Demo in diesem Abschnitt:

  • Erstellt eine Assembly für die Robotersteuerung (GrantImaharaRobotControls.{FILE EXTENSION}) als Razor-Klassenbibliothek (RCL), die eine Robot-Komponente (Robot.razor mit einer Routenvorlage von /robot) einschließt.
  • Lädt die Assembly der RCL verzögert, um die zugehörige Robot-Komponente zu rendern, wenn die /robot-URL vom Benutzer angefordert wird.

Erstellen Sie eine eigenständige Blazor WebAssembly-App, um das Laden der Assembly einer Razor-Klassenbibliothek zu veranschaulichen. Benennen Sie das Projekt mit LazyLoadTest.

Fügen Sie der Projektmappe ein ASP.NET Core-Klassenbibliotheksprojekt hinzu:

  • Visual Studio: Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die Projektmappendatei und, wählen Sie Hinzufügen>Neues Projekt aus. Wählen Sie im Dialogfeld „Neue Projekttypen“ die Option RazorKlassenbibliothek aus. Benennen Sie das Projekt mit GrantImaharaRobotControls. Aktivieren Sie nicht das Kontrollkästchen Seiten und Ansichten unterstützen.
  • Visual Studio Code/.NET CLI: Führen Sie an dotnet new razorclasslib -o GrantImaharaRobotControls einer Eingabeaufforderung aus. Mit der Option -o|--output wird ein Ordner für das Projekt GrantImaharaRobotControls erstellt.

Die Beispielkomponente weiter unten in diesem Abschnitt verwendet ein Blazor-Formular. Fügen Sie das Microsoft.AspNetCore.Components.Forms-Paket im RCL-Projekt dem Projekt hinzu.

Hinweis

Einen Leitfaden zum Hinzufügen von Paketen zu .NET-Apps finden Sie in Installieren und Verwalten von Paketen unter Workflow der Nutzung von Paketen (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.

Erstellen Sie eine HandGesture-Klasse in der RCL mit einer ThumbUp-Methode, die hypothetisch bewirkt, dass ein Roboter mit dem Daumen nach oben zeigt. Die Methode akzeptiert ein Argument für die Achse, Left oder Right, als enum. Die Methode gibt bei einem Erfolg true zurück.

HandGesture.cs:

using Microsoft.Extensions.Logging;

namespace GrantImaharaRobotControls;

public static class HandGesture
{
    public static bool ThumbUp(Axis axis, ILogger logger)
    {
        logger.LogInformation("Thumb up gesture. Axis: {Axis}", axis);

        // Code to make robot perform gesture

        return true;
    }
}

public enum Axis { Left, Right }
using Microsoft.Extensions.Logging;

namespace GrantImaharaRobotControls
{
    public static class HandGesture
    {
        public static bool ThumbUp(Axis axis, ILogger logger)
        {
            logger.LogInformation("Thumb up gesture. Axis: {Axis}", axis);

            // Code to make robot perform gesture

            return true;
        }
    }

    public enum Axis { Left, Right }
}

Fügen Sie zum Stammverzeichnis des RCL-Projekts die folgende Komponente hinzu. Mit der Komponente kann der Benutzer eine Gestenanforderung für den linken oder rechten Daumen übermitteln.

Robot.razor:

@page "/robot"
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.Extensions.Logging
@inject ILogger<Robot> Logger

<h1>Robot</h1>

<EditForm FormName="RobotForm" Model="robotModel" OnValidSubmit="HandleValidSubmit">
    <InputRadioGroup @bind-Value="robotModel.AxisSelection">
        @foreach (var entry in Enum.GetValues<Axis>())
        {
            <InputRadio Value="entry" />
            <text>&nbsp;</text>@entry<br>
        }
    </InputRadioGroup>

    <button type="submit">Submit</button>
</EditForm>

<p>
    @message
</p>

@code {
    private RobotModel robotModel = new() { AxisSelection = Axis.Left };
    private string? message;

    private void HandleValidSubmit()
    {
        Logger.LogInformation("HandleValidSubmit called");

        var result = HandGesture.ThumbUp(robotModel.AxisSelection, Logger);

        message = $"ThumbUp returned {result} at {DateTime.Now}.";
    }

    public class RobotModel
    {
        public Axis AxisSelection { get; set; }
    }
}
@page "/robot"
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.Extensions.Logging
@inject ILogger<Robot> Logger

<h1>Robot</h1>

<EditForm Model="robotModel" OnValidSubmit="HandleValidSubmit">
    <InputRadioGroup @bind-Value="robotModel.AxisSelection">
        @foreach (var entry in Enum.GetValues<Axis>())
        {
            <InputRadio Value="entry" />
            <text>&nbsp;</text>@entry<br>
        }
    </InputRadioGroup>

    <button type="submit">Submit</button>
</EditForm>

<p>
    @message
</p>

@code {
    private RobotModel robotModel = new() { AxisSelection = Axis.Left };
    private string? message;

    private void HandleValidSubmit()
    {
        Logger.LogInformation("HandleValidSubmit called");

        var result = HandGesture.ThumbUp(robotModel.AxisSelection, Logger);

        message = $"ThumbUp returned {result} at {DateTime.Now}.";
    }

    public class RobotModel
    {
        public Axis AxisSelection { get; set; }
    }
}
@page "/robot"
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.Extensions.Logging
@inject ILogger<Robot> Logger

<h1>Robot</h1>

<EditForm Model="robotModel" OnValidSubmit="HandleValidSubmit">
    <InputRadioGroup @bind-Value="robotModel.AxisSelection">
        @foreach (var entry in (Axis[])Enum
            .GetValues(typeof(Axis)))
        {
            <InputRadio Value="entry" />
            <text>&nbsp;</text>@entry<br>
        }
    </InputRadioGroup>

    <button type="submit">Submit</button>
</EditForm>

<p>
    @message
</p>

@code {
    private RobotModel robotModel = new RobotModel() { AxisSelection = Axis.Left };
    private string message;

    private void HandleValidSubmit()
    {
        Logger.LogInformation("HandleValidSubmit called");

        var result = HandGesture.ThumbUp(robotModel.AxisSelection, Logger);

        message = $"ThumbUp returned {result} at {DateTime.Now}.";
    }

    public class RobotModel
    {
        public Axis AxisSelection { get; set; }
    }
}

Erstellen Sie im Projekt LazyLoadTest einen Projektverweis für die GrantImaharaRobotControls-RCL:

  • Visual Studio: Klicken Sie mit der rechten Maustaste auf das LazyLoadTest-Projekt, und wählen Sie Hinzufügen>Projektverweisaus, um einen Projektverweis für die GrantImaharaRobotControls-RCL hinzuzufügen.
  • Visual Studio Code/.NET CLI: Führen Sie dotnet add reference {PATH} in einer Befehlsshell im Ordner des Projekts aus. Der {PATH}-Platzhalter ist der Pfad zum RCL-Projekt.

Geben Sie in der Projektdatei der LazyLoadTest-App (.csproj) an, dass die Assembly der RCL verzögert geladen werden soll:

<ItemGroup>
    <BlazorWebAssemblyLazyLoad Include="GrantImaharaRobotControls.{FILE EXTENSION}" />
</ItemGroup>

Die folgende Router-Komponente veranschaulicht das Laden der GrantImaharaRobotControls.{FILE EXTENSION}-Assembly, wenn der Benutzer zu /robot navigiert. Ersetzen Sie die App-Standardkomponente der App durch die folgende App-Komponente.

Bei Seitenübergängen wird dem Benutzer eine formatierte Meldung mit dem <Navigating>-Element angezeigt. Weitere Informationen finden Sie im Abschnitt Benutzerinteraktion mit <Navigating>-Inhalt.

Die Assembly wird AdditionalAssemblies zugewiesen. Dies führt dazu, dass der Router die Assembly nach routingfähigen Komponenten durchsucht, wobei die Robot-Komponente gefunden wird. Die Route der Robot-Komponente wird zur Routenauflistung der App hinzugefügt. Weitere Informationen finden Sie im Artikel ASP.NET Core: Routing und Navigation in Blazor und im Abschnitt Assemblys, die routingfähige Komponenten enthalten dieses Artikels.

App.razor:

@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject ILogger<App> Logger
@inject LazyAssemblyLoader AssemblyLoader

<Router AppAssembly="typeof(App).Assembly"
        AdditionalAssemblies="lazyLoadedAssemblies" 
        OnNavigateAsync="OnNavigateAsync">
    <Navigating>
        <div style="padding:20px;background-color:blue;color:white">
            <p>Loading the requested page&hellip;</p>
        </div>
    </Navigating>
    <Found Context="routeData">
        <RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="typeof(MainLayout)">
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

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

    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
        {
            if (args.Path == "robot")
            {
                var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                    new[] { "GrantImaharaRobotControls.{FILE EXTENSION}" });
                lazyLoadedAssemblies.AddRange(assemblies);
            }
        }
        catch (Exception ex)
        {
            Logger.LogError("Error: {Message}", ex.Message);
        }
    }
}
@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject ILogger<App> Logger
@inject LazyAssemblyLoader AssemblyLoader

<Router AppAssembly="typeof(Program).Assembly"
        AdditionalAssemblies="lazyLoadedAssemblies" 
        OnNavigateAsync="OnNavigateAsync">
    <Navigating>
        <div style="padding:20px;background-color:blue;color:white">
            <p>Loading the requested page&hellip;</p>
        </div>
    </Navigating>
    <Found Context="routeData">
        <RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="typeof(MainLayout)">
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

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

    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
        {
            if (args.Path == "robot")
            {
                var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                    new[] { "GrantImaharaRobotControls.{FILE EXTENSION}" });
                lazyLoadedAssemblies.AddRange(assemblies);
            }
        }
        catch (Exception ex)
        {
            Logger.LogError("Error: {Message}", ex.Message);
        }
    }
}

Erstellen Sie die App, und führen Sie sie aus.

Wenn die Robot-Komponente der RCL unter /robot angefordert wird, wird die GrantImaharaRobotControls.{FILE EXTENSION}-Assembly geladen und die Robot-Komponente gerendert. Sie können das Laden der Assembly auf der Registerkarte Netzwerk der Entwicklertools des Browsers überprüfen.

Problembehandlung

  • Vergewissern Sie sich bei einem unerwarteten Rendering, z. B. Rendering einer Komponente aus einer vorherigen Navigation, dass der Code ausgelöst wird, wenn das Abbruchtoken festgelegt wird.
  • Überprüfen Sie, ob Assemblys, die für verzögertes Laden beim App-Start konfiguriert sind, aber dennoch geladen werden, in der Projektdatei für verzögertes Laden markiert sind.

Hinweis

Beim Laden von Typen aus einer verzögert geladenen Assembly gibt es ein bekanntes Problem. Weitere Informationen finden Sie unter Blazor WebAssembly lazy loading assemblies not working when using @ref attribute in the component (dotnet/aspnetcore #29342).

Zusätzliche Ressourcen