Megosztás a következőn keresztül:


Az összetevők lusta betöltése az ASP.NET Core-ban Blazor WebAssembly

Jegyzet

Ez nem a cikk legújabb verziója. Az aktuális kiadásról a cikk .NET 10-es verziójában olvashat.

Figyelmeztetés

A ASP.NET Core ezen verziója már nem támogatott. További információ: .NET és .NET Core támogatási szabályzat. Az aktuális kiadás megtekintéséhez nézze meg ennek a cikknek a .NET 9-es verzióját.

Blazor WebAssembly alkalmazásindítási teljesítmény javítható azáltal, hogy a fejlesztő által létrehozott alkalmazásszerelvények csak akkor kerülnek betöltésre, amikor ténylegesen szükség van rájuk, amit késleltetett betöltésnekneveznek.

A cikk kezdeti szakaszai az alkalmazáskonfigurációt ismertetik. A munkabemutatót a cikk végén található Teljes példa című szakaszban találja.

Ez a cikk csak Blazor WebAssembly alkalmazásokra vonatkozik. A komponensek késleltetett betöltése nem előnyös a szerveroldali alkalmazások számára, mert a szerver által renderelt alkalmazások nem töltik le a komponenseket a klienshez.

A késleltetett betöltést nem szabad használni az alapvető futtatókörnyezet-összetevőkhöz, amelyek a közzétételkor levághatók, és nem érhetők el az ügyfélen az alkalmazás betöltésekor.

Fájlkiterjesztés helyőrzője ({FILE EXTENSION}) szerelvényfájlokhoz

A szerelvényfájlok a .NET-szerelvények Webcil csomagolási formátumát használják fájlkiterjesztéssel.

A cikk során a {FILE EXTENSION} helyőrző a "wasm" értéket jelöli.

A szerelvényfájlok Dynamic-Link kódtárakon (DLL-eken) alapulnak .dll fájlkiterjesztéssel.

A cikk során a {FILE EXTENSION} helyőrző a "dll" értéket jelöli.

Projektfájl konfigurálása

Az alkalmazás projektfájljában (.csproj) halasztott betöltésre jelölje meg az összeállításokat a BlazorWebAssemblyLazyLoad elem használatával. Használja a csomag nevét fájlkiterjesztéssel. A Blazor keretrendszer megakadályozza az összeállítás betöltését az alkalmazás indításakor.

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

A {ASSEMBLY NAME} helyőrző az összeállítás neve, a {FILE EXTENSION} helyőrző pedig a fájlkiterjesztés. A fájlkiterjesztés szükséges.

Adjon meg egy BlazorWebAssemblyLazyLoad elemet minden egyes szerelvényhez. Ha egy szerelvény függőségekkel rendelkezik, minden függőséghez adjon meg egy BlazorWebAssemblyLazyLoad bejegyzést.

Router összetevő konfigurációja

A Blazor keretrendszer automatikusan regisztrál egy szingleton szolgáltatást az ügyféloldali Blazor WebAssembly alkalmazásokban a lusta betöltésű összeállításokhoz, LazyAssemblyLoader. A LazyAssemblyLoader.LoadAssembliesAsync módszer:

  • JS interop-t alkalmaz hálózati híváson keresztül szerelvények lekérésére.
  • A böngészőben futó WebAssembly futtatókörnyezetbe tölti be az összetevőket.

Jegyzet

A üzemeltetettBlazor WebAssemblymegoldások útmutatása a lazy load assemblykkel foglalkozik egy üzemeltetett Blazor WebAssembly megoldás szakaszában.

Blazor"Router összetevője kijelöli azokat a szerelvényeket, amelyeket a Blazor keres a megfelelő összetevők után, és felelős az összetevő megjelenítéséért azon az útvonalon is, amelyen a felhasználó navigál. A Router komponens OnNavigateAsync metódusát a késleltetett betöltéssel együtt használják a megfelelő szerelvényeknek a felhasználó által kért végpontokhoz történő betöltésére.

A logika a OnNavigateAsync belsejében van implementálva, hogy meghatározza a LazyAssemblyLoaderbetöltendő összeállításokat. A logika felépítésének lehetőségei a következők:

  • Feltételes ellenőrzések a OnNavigateAsync metóduson belül.
  • Egy keresési tábla, amely útvonalakat rendel összeállítási nevekhez, ezt vagy az összetevőbe injektálják, vagy az összetevő kódjában valósítják meg.

Az alábbi példában:

  • Meg van adva a Microsoft.AspNetCore.Components.WebAssembly.Services névtere.
  • A LazyAssemblyLoader szolgáltatás injektálva van (AssemblyLoader).
  • A {PATH} helyőrző az az elérési út, ahová az összeállítások listáját kell betölteni. A példa feltételes ellenőrzést használ egy útvonal esetében, amely egyetlen assembly-ket tölt be.
  • A {LIST OF ASSEMBLIES} helyőrző a fájlnevek, beleértve a fájlkiterjesztéseket, vesszővel elválasztott listája (például "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);
           }
    }
}

Jegyzet

Az előző példa nem mutatja a Router komponens Razor jelölésének (...) tartalmát. A teljes kóddal rendelkező bemutatót a cikk Teljes példa című szakaszában találja.

Jegyzet

A .NET 5.0.1 kiadásával és minden további 5.x kiadás esetén az Router összetevő tartalmazza a PreferExactMatches következő paramétert @true: . További információ: Migrálás ASP.NET Core 3.1-ről .NET 5-be.

Útválasztható összetevőket tartalmazó szerelvények

Ha a szerelvények listája útválasztóképes összetevőket tartalmaz, az adott útvonalhoz tartozó szerelvénylistát a rendszer átadja a Router összetevő AdditionalAssemblies gyűjteményének.

Az alábbi példában:

  • A -ben található <Assembly>lazyLoadedAssemblies a szerelvénylistát továbbítja AdditionalAssemblies-nak. A keretrendszer útvonalakat keres az összeállításokban, és frissíti az útvonalgyűjteményt, ha új útvonalakat talál. A Assembly típus eléréséhez a System.Reflection névtere a App.razor fájl tetején található.
  • A {PATH} helyőrző az az elérési út, ahová az összeállítások listáját kell betölteni. A példa feltételes ellenőrzést használ egy útvonal esetében, amely egyetlen assembly-ket tölt be.
  • A {LIST OF ASSEMBLIES} helyőrző a fájlnevek, beleértve a fájlkiterjesztéseket, vesszővel elválasztott listája (például "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);
           }
    }
}

Jegyzet

Az előző példa nem mutatja a Router komponens Razor jelölésének (...) tartalmát. A teljes kóddal rendelkező bemutatót a cikk Teljes példa című szakaszában találja.

Jegyzet

A .NET 5.0.1 kiadásával és minden további 5.x kiadás esetén az Router összetevő tartalmazza a PreferExactMatches következő paramétert @true: . További információ: Migrálás ASP.NET Core 3.1-ről .NET 5-be.

További információkért lásd az ASP.NET Core Blazor útválasztás és navigációrészt.

Felhasználói interakció <Navigating> tartalommal

A szerelvények betöltésekor, amely több másodpercig is eltarthat, a Router összetevő jelezheti a felhasználónak, hogy az útválasztó Navigating tulajdonságával oldalon történő átmenet zajlik.

További információkért lásd az ASP.NET Core Blazor útválasztás és navigációrészt.

Lemondások kezelése a OnNavigateAsync

A NavigationContext visszahívásnak átadott OnNavigateAsync objektum tartalmaz egy CancellationToken-t, amely beállításra kerül, amikor egy új navigációs esemény bekövetkezik. A OnNavigateAsync visszahívásnak a lemondási token beállításakor kell dobnia, hogy elkerülje a OnNavigateAsync visszahívás folytatását egy elavult navigáció során.

További információkért lásd az ASP.NET Core Blazor útválasztás és navigációrészt.

OnNavigateAsync események és átnevezett összeállítási fájlok

Az erőforrás-betöltő a rendszerindítási jegyzékfájlban definiált szerelvénynevekre támaszkodik. Ha a szerelvények átnevezve vannak, a visszahívásban OnNavigateAsync használt szerelvénynevek és a rendszerindítási jegyzékfájlban lévő szerelvénynevek nem szinkronizálódnak.

A hiba kijavítása:

  • Ellenőrizze, hogy az alkalmazás a Production környezetben fut-e, amikor meghatározza, hogy mely szerelvényneveket kell használni.
  • Tárolja az átnevezett szerelvényneveket egy külön fájlban, és olvassa be a fájl tartalmát annak meghatározására, hogy melyik szerelvénynevet használja a LazyAssemblyLoader szolgáltatással és a OnNavigateAsync visszahívással.

- Lusta betöltésű assembly-k hosztolt Blazor WebAssembly megoldásban

A keretrendszer késleltetett betöltési implementációja támogatja a késleltetett betöltést és az előrenderelést egy hosztolt Blazor WebAssemblymegoldásesetén. Az előrenderelés során feltételezzük, hogy minden programkönyvtár be van töltve, beleértve azokat is, amelyeket késleltetett betöltésre jelöltek meg. Manuálisan regisztrálja a LazyAssemblyLoader szolgáltatást a Server projektben.

A Program.cs projekt Server fájljának tetején adja hozzá a Microsoft.AspNetCore.Components.WebAssembly.Servicesnévterét:

using Microsoft.AspNetCore.Components.WebAssembly.Services;

A Program.cs projekt Server-jában regisztrálja a szolgáltatást:

builder.Services.AddScoped<LazyAssemblyLoader>();

A Startup.cs projekt Server fájljának tetején adja hozzá a Microsoft.AspNetCore.Components.WebAssembly.Servicesnévterét:

using Microsoft.AspNetCore.Components.WebAssembly.Services;

A Startup.ConfigureServices projekt Startup.cs (Server) részében regisztrálja a szolgáltatást:

services.AddScoped<LazyAssemblyLoader>();

Teljes példa

A bemutató ebben a szakaszban:

  • Létrehoz egy robotvezérlő-szerelvényt (GrantImaharaRobotControls.{FILE EXTENSION}) Razor osztálykódtárként (RCL), amely tartalmaz egy Robot összetevőt (Robot.razor/robotútvonalsablonjával).
  • Lassan tölti be az RCL szerelvényét, hogy megjelenítse a Robot komponensét, amikor a felhasználó a /robot URL-t kéri.

Hozzon létre egy önálló Blazor WebAssembly alkalmazást, amely bemutatja egy Razor osztálykönyvtár assembly lusta betöltését. Nevezze el a projekt LazyLoadTest.

Adjon hozzá egy ASP.NET Core osztálytárprojektet a megoldáshoz:

  • Visual Studio: Kattintson a jobb gombbal a megoldásfájlra Megoldáskezelő, és válassza a >Új projekt hozzáadásalehetőséget. Az új projekttípusok párbeszédpanelén válassza Razor Osztálytárlehetőséget. Nevezze el a projekt GrantImaharaRobotControls. Ne jelölje be a támogatási lapokat és nézeteket jelölőnégyzetet.
  • Visual Studio Code/.NET CLI: A dotnet new razorclasslib -o GrantImaharaRobotControls végrehajtása a parancssorból. A -o|--output beállítás létrehoz egy mappát, és elnevozza a projekt GrantImaharaRobotControls.

Hozzon létre egy HandGesture osztályt az RCL-ben azzal a ThumbUp metódussal, ami hipotetikusan egy robottal ergo egy hüvelykujjával felfelé mutató mozdulatot hajt végre. A metódus egy argumentumot fogad el a tengelyhez, legyen az Left vagy Right, mint enum. A metódus siker esetén true-t ad vissza.

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

Adja hozzá a következő összetevőt az RCL-projekt gyökeréhez. Az összetevő lehetővé teszi, hogy a felhasználó bal vagy jobb kéz kézmozdulat-kérést küldjön.

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

A LazyLoadTest projektben hozzon létre egy projekthivatkozást a GrantImaharaRobotControls RCL-hez:

  • Visual Studio: Kattintson a jobb gombbal a LazyLoadTest projektre, és válassza a >projekthivatkozás hozzáadása lehetőséget a GrantImaharaRobotControls RCL projekthivatkozásának hozzáadásához.
  • Visual Studio Code/.NET CLI: dotnet add reference {PATH} végrehajtása a parancssorban a projekt mappájából. A {PATH} helyőrző az RCL-projekt elérési útvonala.

Adja meg az RCL összeállítását a lazy loadinghez az LazyLoadTest alkalmazás projektfájljában (.csproj):

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

Az alábbi Router összetevő bemutatja a GrantImaharaRobotControls.{FILE EXTENSION} szerelvény betöltését, amikor a felhasználó navigál a /robot-hez. Cserélje le az alkalmazás alapértelmezett App összetevőjét a következő App összetevőre.

Az oldaláttűnések során a <Navigating> elemet tartalmazó felhasználó számára stílusüzenet jelenik meg. További információ: Felhasználói interakció <Navigating> tartalommal szakasz.

A szerelvény a AdditionalAssemblies-hoz van hozzárendelve, aminek az az eredménye, hogy az útválasztó megkeresi benne az útválasztható összetevőket és megtalálja a Robot összetevőt. A Robot összetevő útvonala hozzá lesz adva az alkalmazás útvonalgyűjteményéhez. További információkért tekintse meg a ASP.NET Core útválasztási és navigációs cikket, valamint ennek a cikknek az útvonalazható összetevőket tartalmazó szerelvényeit.

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

Hozza létre és futtassa az alkalmazást.

Amikor az RCL Robot összetevőjét kéri le /robot, a rendszer betölti a GrantImaharaRobotControls.{FILE EXTENSION} szerelvényt, és rendereli a Robot összetevőt. A böngésző fejlesztői eszközeinek Hálózat fülén megtekintheti az összeállítás betöltését.

Hibakeresés

  • Ha váratlan renderelés történik, például egy előző navigációs összetevő renderelése, győződjön meg arról, hogy a kód kivételt dob, ha a törlési token be van állítva.
  • Ha a lusta betöltéshez konfigurált szerelvények váratlanul betöltődnek az alkalmazás indításakor, ellenőrizze, hogy a szerelvény a projektfájl lusta betöltésére van-e megjelölve.

Jegyzet

Ismert probléma áll fenn a típusok lazán betöltött szerelvényből való betöltésével kapcsolatban. További információ: Blazor WebAssembly lazy loading assemblies not working when using @ref attribute in the component (dotnet/aspnetcore #29342).

További erőforrások