Delen via


Lazy load van assemblies in ASP.NET Core Blazor WebAssembly

Opmerking

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Waarschuwing

Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie de .NET- en .NET Core-ondersteuningsbeleidvoor meer informatie. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Belangrijk

Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.

Zie de .NET 9-versie van dit artikelvoor de huidige release.

Blazor WebAssembly De opstartprestaties van apps kunnen worden verbeterd door het laden van door ontwikkelaars gemaakte app-assembly's uit te stellen totdat ze nodig zijn. Dit wordt lui laden genoemd.

In de eerste secties van dit artikel wordt de app-configuratie behandeld. Zie de sectie Volledig voorbeeld aan het einde van dit artikel voor een werkende demonstratie.

Dit artikel is alleen van toepassing op Blazor WebAssembly apps. Lazy loading van assembly's biedt geen voordeel voor servergerichte apps omdat deze apps geen assembly's naar de client downloaden.

Lazy loading moet niet worden gebruikt voor kernruntime-assemblies, die mogelijk worden uitgesneden bij publicatie en niet beschikbaar zijn op de client wanneer de app wordt geladen.

Bestandsextensie placeholder ({FILE EXTENSION}) voor assemblagebestanden

Assemblybestanden maken gebruik van de webcilverpakkingsindeling voor .NET-assembly's met een .wasm bestandsextensie.

In het hele artikel vertegenwoordigt de {FILE EXTENSION} placeholder 'wasm'.

Assemblybestanden zijn gebaseerd op Dynamic-Link Bibliotheken (DLL's) met een .dll bestandsextensie.

In het hele artikel vertegenwoordigt de {FILE EXTENSION} placeholder 'dll'.

Configuratie van projectbestand

Markeer assemblies voor lui laden in het toepassingsprojectbestand (.csproj) met het item BlazorWebAssemblyLazyLoad. Gebruik de assemblage naam met bestandsextensie. Het Blazor framework voorkomt dat de assembly wordt geladen bij het starten van de app.

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

De {ASSEMBLY NAME} tijdelijke aanduiding is de naam van de assembly en de {FILE EXTENSION} tijdelijke aanduiding is de bestandsextensie. Een bestandsextensie is vereist.

Neem één BlazorWebAssemblyLazyLoad item op voor elke assembly. Als een assembly afhankelijkheden heeft, neemt u een BlazorWebAssemblyLazyLoad vermelding op voor elke afhankelijkheid.

Router configuratie van onderdelen

Het Blazor framework registreert automatisch een singleton-service voor lazy-loading assemblages in client-side Blazor WebAssembly apps, LazyAssemblyLoader. De methode LazyAssemblyLoader.LoadAssembliesAsync:

  • Maakt gebruik JS van interop om assembly's op te halen via een netwerkoproep.
  • Laadt assemblies in de runtime die op WebAssembly in de browser wordt uitgevoerd.

Opmerking

Richtlijnen voor gehosteBlazor WebAssemblyoplossingen worden behandeld in de sectie Lazy load-assemblages in een gehoste Blazor WebAssembly oplossing.

Blazor's Router component wijst de assemblages aan die Blazor doorzoekt op routeerbare componenten en is ook verantwoordelijk voor het renderen van de component voor de route waar de gebruiker naartoe navigeert. De Router component heeft de methode OnNavigateAsync die gebruikt wordt in combinatie met lazy loading om de juiste assemblies te laden voor de eindpunten die een gebruiker opvraagt.

Logica wordt binnen OnNavigateAsync geïmplementeerd om te bepalen welke assembly's geladen moeten worden met LazyAssemblyLoader. Opties voor het structuren van de logica zijn onder andere:

  • Voorwaardelijke controles binnen de OnNavigateAsync methode.
  • Een opzoektabel die routes mapt naar assembly-namen, die ofwel in de component worden geïnjecteerd of in de code van de component worden geïmplementeerd.

In het volgende voorbeeld:

  • De naamruimte voor Microsoft.AspNetCore.Components.WebAssembly.Services is opgegeven.
  • De LazyAssemblyLoader service wordt geïnjecteerd (AssemblyLoader).
  • De {PATH} tijdelijke aanduiding is het pad waarin de lijst met assemblies geladen moet worden. In het voorbeeld wordt een voorwaardelijke controle gebruikt voor één pad dat een enkele set assemblies laadt.
  • De {LIST OF ASSEMBLIES} tijdelijke aanduiding is de door komma's gescheiden lijst met tekenreeksen voor assemblybestandsnamen, inclusief de bestandsextensies (bijvoorbeeld "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(
                       [ {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(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);
           }
    }
}

Opmerking

In het voorgaande voorbeeld wordt de inhoud van de opmaak van het Router onderdeel Razor (...) niet weergegeven. Zie de sectie Volledig voorbeeld van dit artikel voor een demonstratie met volledige code.

Opmerking

Met de release van .NET 5.0.1 en voor eventuele extra releases van 5.x bevat het Router onderdeel de PreferExactMatches parameter die is ingesteld op @true. Zie Migreren van ASP.NET Core 3.1 naar .NET 5 voor meer informatie.

Assemblages met routeerbare componenten

Wanneer de lijst met assembly's routeerbare onderdelen bevat, wordt de assemblylijst voor een bepaald pad doorgegeven aan de Router component's AdditionalAssemblies collectie.

In het volgende voorbeeld:

  • De lijst<Assembly> in lazyLoadedAssemblies geeft de samenstellingslijst door aan AdditionalAssemblies. Het framework doorzoekt de assembly's op routes en werkt de routeverzameling bij als er nieuwe routes worden gevonden. Voor toegang tot het Assembly type wordt de naamruimte voor System.Reflection bovenaan het App.razor bestand opgenomen.
  • De {PATH} tijdelijke aanduiding is het pad waarin de lijst met assemblies geladen moet worden. In het voorbeeld wordt een voorwaardelijke controle gebruikt voor één pad dat een enkele set assemblies laadt.
  • De {LIST OF ASSEMBLIES} tijdelijke aanduiding is de door komma's gescheiden lijst met tekenreeksen voor assemblybestandsnamen, inclusief de bestandsextensies (bijvoorbeeld "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 = [];

    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
        {
            if (args.Path == "{PATH}")
            {
                var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                    [ {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(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);
           }
    }
}

Opmerking

In het voorgaande voorbeeld wordt de inhoud van de opmaak van het Router onderdeel Razor (...) niet weergegeven. Zie de sectie Volledig voorbeeld van dit artikel voor een demonstratie met volledige code.

Opmerking

Met de release van .NET 5.0.1 en voor eventuele extra releases van 5.x bevat het Router onderdeel de PreferExactMatches parameter die is ingesteld op @true. Zie Migreren van ASP.NET Core 3.1 naar .NET 5 voor meer informatie.

Zie ASP.NET Core Blazor routering en navigatievoor meer informatie.

Gebruikersinteractie met <Navigating> inhoud

Tijdens het laden van assembly's, wat enkele seconden kan duren, kan het Router-onderdeel aan de gebruiker aangeven dat er een paginaovergang plaatsvindt met de eigenschap van de router Navigating.

Zie ASP.NET Core Blazor routering en navigatievoor meer informatie.

Annuleringen in OnNavigateAsync verwerken

Het NavigationContext-object dat wordt doorgegeven aan de OnNavigateAsync callback bevat een CancellationToken die is ingesteld wanneer er een nieuwe navigatiegebeurtenis plaatsvindt. De OnNavigateAsync callback moet een uitzondering geven wanneer de annulerings-token is ingesteld, om te voorkomen dat de OnNavigateAsync callback doorgaat met uitvoeren op verouderde navigatie.

Zie ASP.NET Core Blazor routering en navigatievoor meer informatie.

OnNavigateAsync gebeurtenissen en hernoemde assembly-bestanden

Het resourcelaadprogramma is afhankelijk van de assemblynamen die zijn gedefinieerd in het opstartmanifestbestand. Als de naam van assembly's wordt gewijzigd, zijn de assemblynamen die worden gebruikt in een OnNavigateAsync callback en de assemblynamen in het opstartmanifestbestand niet gesynchroniseerd.

Ga als volgt te werk om dit te verhelpen:

  • Controleer of de app wordt uitgevoerd in de Production omgeving wanneer u bepaalt welke assemblynamen moeten worden gebruikt.
  • Sla de hernoemde assemblynamen op in een afzonderlijk bestand en lees uit dat bestand om te bepalen welke assemblynaam moet worden gebruikt met de LazyAssemblyLoader service en OnNavigateAsync callback.

Lazy loading assemblies in een gehoste Blazor WebAssembly oplossing

De implementatie voor lazy loading in het framework biedt ondersteuning voor lazy loading met prerendering in een gehoste Blazor WebAssemblyoplossing. Tijdens het prerenderen worden alle assemblages, inclusief de assemblages die zijn gemarkeerd voor luie laden, ervan uitgegaan dat ze geladen zijn. Registreer de LazyAssemblyLoader service handmatig in het Server project.

Voeg boven aan het bestand van het Program.csServer project de naamruimte toe voor Microsoft.AspNetCore.Components.WebAssembly.Services:

using Microsoft.AspNetCore.Components.WebAssembly.Services;

Program.cs Registreer de service in het Server project:

builder.Services.AddScoped<LazyAssemblyLoader>();

Voeg boven aan het bestand van het Startup.csServer project de naamruimte toe voor Microsoft.AspNetCore.Components.WebAssembly.Services:

using Microsoft.AspNetCore.Components.WebAssembly.Services;

Registreer de service in Startup.ConfigureServices (Startup.cs) van het Server project:

services.AddScoped<LazyAssemblyLoader>();

Volledig voorbeeld

De demonstratie in deze sectie:

  • Hiermee maakt u een robotbesturingsassembly (GrantImaharaRobotControls.{FILE EXTENSION}) als een Razor klassebibliotheek (RCL) die een Robot onderdeel (Robot.razor met een routesjabloon /robot) bevat.
  • Lazily laadt de assembly van de RCL om het Robot onderdeel weer te geven wanneer de /robot URL wordt aangevraagd door de gebruiker.

Maak een zelfstandige Blazor WebAssembly app om het lazy loading van de assembly van een Razor klassebibliotheek te demonstreren. Geef het project de naam LazyLoadTest.

Voeg een ASP.NET Core-klassebibliotheekproject toe aan de oplossing:

  • Visual Studio: Klik met de rechtermuisknop op het oplossingsbestand in Solution Explorer en selecteerNieuw project>. Selecteer Razor Klassebibliotheek in het dialoogvenster met nieuwe projecttypen. Geef het project de naam GrantImaharaRobotControls. Selecteer het selectievakje voor ondersteuningspagina's en weergavenniet.
  • Visual Studio Code/.NET CLI: Uitvoeren dotnet new razorclasslib -o GrantImaharaRobotControls vanaf een opdrachtprompt. Met de -o|--output optie maakt u een map en geeft u het project GrantImaharaRobotControlseen naam.

Maak een HandGesture klasse in de RCL met een ThumbUp methode die hypothetisch een robot een duimbeweging laat uitvoeren. De methode accepteert een argument voor de as, Left of Right, als een enum. De methode retourneert true bij succes.

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 }
}

Voeg de volgende component toe aan de basis van het RCL-project. Met het onderdeel kan de gebruiker een aanvraag voor een linker- of rechtervingerbeweging indienen.

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; }
    }
}

Maak in het LazyLoadTest project een projectreferentie voor de GrantImaharaRobotControls RCL:

  • Visual Studio: klik met de rechtermuisknop op het LazyLoadTest project en selecteerProjectverwijzing> om een projectverwijzing voor de GrantImaharaRobotControls RCL toe te voegen.
  • Visual Studio Code/.NET CLI: Voer dotnet add reference {PATH} uit in een opdrachtprompt vanuit de projectmap. De {PATH} placeholder is het pad naar het RCL-project.

Geef de assembly van de RCL op voor lazy loading in het projectbestand van de LazyLoadTest app (.csproj):

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

Het volgende Router onderdeel laat zien hoe de GrantImaharaRobotControls.{FILE EXTENSION} assembly wordt geladen wanneer de gebruiker naartoe /robotnavigeert. Vervang het standaardonderdeel App van de app door het volgende App onderdeel.

Tijdens paginaovergangen wordt een gestijld bericht weergegeven aan de gebruiker met het <Navigating> element. Zie de sectie Gebruikersinteractie met <Navigating> inhoud voor meer informatie.

De assembly wordt toegewezen aan AdditionalAssemblies, wat ertoe leidt dat de router de assembly doorzoekt op routeerbare onderdelen, waar het Robot onderdeel wordt gevonden. De Robot route van het onderdeel wordt toegevoegd aan de routeverzameling van de app. Zie het artikel over routering en navigatie van ASP.NET Core Blazor en de assembly's met routeerbare onderdelen van dit artikel voor meer informatie.

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 = [];
    private bool grantImaharaRobotControlsAssemblyLoaded;

    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
        {
            if ((args.Path == "robot") && !grantImaharaRobotControlsAssemblyLoaded)
            {
                var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                    [ "GrantImaharaRobotControls.{FILE EXTENSION}" ]);
                lazyLoadedAssemblies.AddRange(assemblies);
                grantImaharaRobotControlsAssemblyLoaded = true;
            }
        }
        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(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 bool grantImaharaRobotControlsAssemblyLoaded;

    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
        {
            if ((args.Path == "robot") && !grantImaharaRobotControlsAssemblyLoaded)
            {
                var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                    new[] { "GrantImaharaRobotControls.{FILE EXTENSION}" });
                lazyLoadedAssemblies.AddRange(assemblies);
                grantImaharaRobotControlsAssemblyLoaded = true;
            }
        }
        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 bool grantImaharaRobotControlsAssemblyLoaded;

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

Bouw en voer de app uit.

Wanneer het Robot onderdeel van de RCL op /robot wordt aangevraagd, wordt de GrantImaharaRobotControls.{FILE EXTENSION} assembly geladen en wordt het Robot onderdeel weergegeven. U kunt het laden van de assembly controleren op het tabblad Netwerk van de ontwikkelhulpprogramma's van de browser.

Problemen oplossen

  • Als er onverwachte rendering optreedt, zoals het renderen van een component uit een vorige navigatie, controleer dan of de code een uitzondering geeft als het annulerings-token is ingesteld.
  • Als assemblies die zijn geconfigureerd voor luie laden onverwachts laden bij het starten van de app, controleert u of de assembly is gemarkeerd voor luie laden in het projectbestand.

Opmerking

Er bestaat een bekend probleem voor het laden van typen van een lui-geladen assembly. Zie Blazor WebAssembly lazy loading assemblies not working when using @ref attribute in the component (dotnet/aspnetcore #29342) voor meer informatie.

Aanvullende bronnen