ASP.NET Core Blazor WebAssembly의 어셈블리 지연 로드

참고 항목

이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

Important

이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.

현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

Blazor WebAssembly어셈블리가 필요할 때까지 개발자가 만든 앱 어셈블리를 로드하기 위해 대기하여 앱 시작 성능을 향상시킬 수 있습니다. 이를 지연 로드라고 합니다.

이 문서의 초기 섹션에서는 앱 구성을 다룹니다. 작동하는 데모는 이 문서의 끝부분에 있는 전체 예제 섹션을 참조하세요.

이 문서는 Blazor WebAssembly 앱에만 적용됩니다. 어셈블리 지연 로드는 서버 렌더링 앱이 클라이언트에 어셈블리를 다운로드하지 않으므로 서버 쪽 앱에 도움이 되지 않습니다.

지연 로드는 핵심 런타임 어셈블리에 사용해서는 안 됩니다. 이 어셈블리는 게시 시 잘리고 앱이 로드될 때 클라이언트에서 사용할 수 없습니다.

어셈블리 파일의 파일 확장자 자리 표시자({FILE EXTENSION})

어셈블리 파일은 파일 확장자를 사용하는 .NET 어셈블리 에 웹빌 패키징 형식을 .wasm 사용합니다.

아티클 전체에서 {FILE EXTENSION} 자리 표시자는 "wasm"를 나타냅니다.

어셈블리 파일은 파일 확장자를 사용하는 DLL(동적 연결 라이브러리)을 기반으로 합니다 .dll .

아티클 전체에서 {FILE EXTENSION} 자리 표시자는 "dll"를 나타냅니다.

프로젝트 파일 구성

BlazorWebAssemblyLazyLoad 항목을 사용하여 앱의 프로젝트 파일(.csproj)에서 어셈블리를 지연 로드로 표시합니다. 파일 확장명에서 어셈블리 이름을 사용합니다. Blazor 프레임워크는 앱 시작 시 어셈블리가 로드되지 않도록 합니다.

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

{ASSEMBLY NAME} 자리 표시자는 어셈블리의 이름이고 {FILE EXTENSION} 자리 표시자는 파일 확장명입니다. 파일 확장명은 필수입니다.

각 어셈블리에 대해 BlazorWebAssemblyLazyLoad 항목을 하나씩 포함합니다. 어셈블리에 종속성이 있는 경우 각 종속성에 대해 BlazorWebAssemblyLazyLoad 항목을 하나씩 포함합니다.

Router 구성 요소 구성

프레임워크는 Blazor 클라이언트 쪽 Blazor WebAssembly 앱 LazyAssemblyLoader에서 어셈블리를 지연 로드하기 위해 싱글톤 서비스를 자동으로 등록합니다. LazyAssemblyLoader.LoadAssembliesAsync 메서드는 다음 작업을 수행합니다.

  • JS interop을 사용하여 네트워크 호출을 통해 어셈블리를 페치합니다.
  • 브라우저의 WebAssembly에서 실행되는 런타임에 어셈블리를 로드합니다.

참고 항목

호스트된 솔루션에 대한 지침은 호스트Blazor WebAssemblyBlazor WebAssembly된 솔루션 섹션의 지연 로드 어셈블리에서 다룹니다.

Blazor의 Router 구성 요소는 Blazor가 라우팅 가능한 구성 요소를 검색하는 어셈블리를 지정하며 사용자가 탐색하는 경로의 구성 요소를 렌더링하는 작업도 담당합니다. Router 구성 요소의 OnNavigateAsync 메서드는 지연 로드와 함께 사용되어 사용자가 요청하는 엔드포인트에 대한 올바른 어셈블리를 로드합니다.

LazyAssemblyLoader로 로드할 어셈블리를 결정하는 논리는 OnNavigateAsync 내부에 구현됩니다. 이 논리를 구성하는 방법에 대한 옵션은 다음과 같습니다.

  • OnNavigateAsync 메서드 내의 조건부 검사입니다.
  • 구성 요소에 삽입되거나 @code 블록 내에서 구현되는 경로를 어셈블리 이름에 매핑하는 조회 테이블입니다.

다음 예제에서

  • Microsoft.AspNetCore.Components.WebAssembly.Services의 네임스페이스가 지정됩니다.
  • LazyAssemblyLoader 서비스가 삽입됩니다(AssemblyLoader).
  • {PATH} 자리 표시자는 어셈블리 목록이 로드되어야 하는 경로입니다. 이 예제에서는 단일 어셈블리 집합을 로드하는 단일 경로에 대해 조건부 검사를 사용합니다.
  • {LIST OF ASSEMBLIES} 자리 표시자는 파일 확장명(예"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);
           }
    }
}

참고 항목

앞의 예제에서는 Router 구성 요소의 Razor 태그(...) 내용을 표시하지 않습니다. 전체 코드가 포함된 데모는 이 문서의 전체 예제 섹션을 참조하세요.

참고 항목

ASP.NET Core 5.0.1 릴리스 및 추가 5.x 릴리스부터 Router 구성 요소에는 @true로 설정된 PreferExactMatches 매개 변수가 포함됩니다. 자세한 내용은 ASP.NET Core 3.1에서 5.0으로 마이그레이션을 참조하세요.

라우팅 가능한 구성 요소를 포함하는 어셈블리

어셈블리 목록에 라우팅 가능한 구성 요소가 포함되어 있으면 지정된 경로에 대한 어셈블리 목록이 Router 구성 요소의 AdditionalAssemblies 컬렉션에 전달됩니다.

다음 예제에서

  • lazyLoadedAssembliesList<Assembly>는 어셈블리 목록을 AdditionalAssemblies에 전달합니다. 이 프레임워크는 어셈블리에서 경로를 검색하고 새 경로를 찾으면 경로 컬렉션을 업데이트합니다. Assembly 형식에 액세스하기 위해 System.Reflection의 네임스페이스가 App.razor 파일 맨 위에 포함됩니다.
  • {PATH} 자리 표시자는 어셈블리 목록이 로드되어야 하는 경로입니다. 이 예제에서는 단일 어셈블리 집합을 로드하는 단일 경로에 대해 조건부 검사를 사용합니다.
  • {LIST OF ASSEMBLIES} 자리 표시자는 파일 확장명(예"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);
           }
    }
}

참고 항목

앞의 예제에서는 Router 구성 요소의 Razor 태그(...) 내용을 표시하지 않습니다. 전체 코드가 포함된 데모는 이 문서의 전체 예제 섹션을 참조하세요.

참고 항목

ASP.NET Core 5.0.1 릴리스 및 추가 5.x 릴리스부터 Router 구성 요소에는 @true로 설정된 PreferExactMatches 매개 변수가 포함됩니다. 자세한 내용은 ASP.NET Core 3.1에서 5.0으로 마이그레이션을 참조하세요.

자세한 내용은 ASP.NET Core Blazor 라우팅 및 탐색을 참조하세요.

<Navigating> 콘텐츠와의 사용자 상호 작용

몇 초 정도 걸릴 수 있는 어셈블리 로드 중에 Router 구성 요소는 라우터의 Navigating 속성을 사용하여 페이지 전환 중임을 사용자에게 나타낼 수 있습니다.

자세한 내용은 ASP.NET Core Blazor 라우팅 및 탐색을 참조하세요.

OnNavigateAsync에서의 취소 처리

OnNavigateAsync 콜백에 전달되는 NavigationContext 개체에는 새 탐색 이벤트가 발생할 때 설정되는 CancellationToken이 포함됩니다. 오래된 탐색에서 OnNavigateAsync 콜백을 계속 실행하지 않도록 취소 토큰이 설정된 경우 OnNavigateAsync 콜백을 throw해야 합니다.

자세한 내용은 ASP.NET Core Blazor 라우팅 및 탐색을 참조하세요.

OnNavigateAsync 이벤트 및 이름이 바뀐 어셈블리 파일

리소스 로더는 blazor.boot.json 파일에 정의된 어셈블리 이름을 사용합니다. 어셈블리 이름이 바뀐 경우 OnNavigateAsync 콜백에 사용된 어셈블리 이름과 blazor.boot.json 파일의 어셈블리 이름이 동기화되지 않습니다.

해결하려면 다음을 수행합니다.

  • 사용할 어셈블리 이름을 결정할 때 앱이 Production 환경에서 실행되고 있는지 확인합니다.
  • 바뀐 어셈블리 이름을 별도의 파일에 저장하고 해당 파일에서 읽어 LazyAssemblyLoader 서비스와 OnNavigateAsync 콜백에 사용할 어셈블리 이름을 결정합니다.

호스트된 Blazor WebAssembly 솔루션에서 어셈블리 지연 로드

프레임워크의 지연 로드 구현에서는 호스트된 Blazor WebAssembly솔루션에서 미리 렌더링으로 지연 로드를 지원합니다. 미리 렌더링 중에는 지연 로드로 표시된 어셈블리를 포함한 모든 어셈블리가 로드된다고 가정합니다. LazyAssemblyLoader 서비스를 Server 프로젝트에 수동으로 등록합니다.

Server 프로젝트 Program.cs 파일의 맨 위에 Microsoft.AspNetCore.Components.WebAssembly.Services의 네임스페이스를 추가합니다.

using Microsoft.AspNetCore.Components.WebAssembly.Services;

Server 프로젝트의 Program.cs에서 서비스를 등록합니다.

builder.Services.AddScoped<LazyAssemblyLoader>();

Server 프로젝트 Startup.cs 파일의 맨 위에 Microsoft.AspNetCore.Components.WebAssembly.Services의 네임스페이스를 추가합니다.

using Microsoft.AspNetCore.Components.WebAssembly.Services;

프로젝트의 (Startup.cs)Server에서 Startup.ConfigureServices 서비스를 등록합니다.

services.AddScoped<LazyAssemblyLoader>();

전체 예제

이 섹션의 데모:

  • Robot 구성 요소(경로 템플릿 /robot을 사용한 Robot.razor)를 포함하는 RCL(Razor 클래스 라이브러리)로 로봇 컨트롤 어셈블리(GrantImaharaRobotControls.{FILE EXTENSION})를 만듭니다.
  • 사용자가 /robot URL을 요청할 때 RCL의 어셈블리를 지연 로드하여 해당 Robot 구성 요소를 렌더링합니다.

클래스 라이브러리 어셈블리의 지연 로드를 Razor 보여 주는 독립 실행형 Blazor WebAssembly 앱을 만듭니다. 프로젝트 이름을 LazyLoadTest로 지정합니다.

솔루션에 ASP.NET Core 클래스 라이브러리 프로젝트를 추가합니다.

  • Visual Studio: 솔루션 탐색기 솔루션 파일을 마우스 오른쪽 단추로 클릭하고 새 프로젝트 추가>를 선택합니다. 새 프로젝트 형식 대화 상자에서 클래스 라이브러리를 선택합니다.Razor 프로젝트 이름을 GrantImaharaRobotControls로 지정합니다. 지원 페이지를 선택하고 검사 상자를 보지 마세요.
  • Visual Studio Code/.NET CLI: 명령 프롬프트에서 dotnet new razorclasslib -o GrantImaharaRobotControls를 실행합니다. 이 -o|--output 옵션은 폴더를 만들고 프로젝트의 GrantImaharaRobotControls이름을 지정합니다.

이 섹션의 뒷부분에 제공된 예제 구성 요소는 Blazor 양식을 사용합니다. RCL 프로젝트에서 Microsoft.AspNetCore.Components.Forms 패키지를 프로젝트에 추가합니다.

참고 항목

.NET 앱에 패키지를 추가하는 방법에 대한 지침은 패키지 사용 워크플로에서 패키지 설치 및 관리의 문서(NuGet 설명서)를 참조하세요. NuGet.org에서 올바른 패키지 버전을 확인합니다.

가상으로 로봇이 엄지손가락 들기 제스처를 수행하게 만드는 ThumbUp 메서드를 사용하여 RCL에 HandGesture 클래스를 만듭니다. 이 메서드는 축의 인수 Left 또는 Rightenum으로 수락합니다. 성공하면 이 메서드는 true를 반환합니다.

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

RCL 프로젝트의 루트에 다음 구성 요소를 추가합니다. 이 구성 요소를 사용하면 사용자가 왼쪽 또는 오른쪽 손 엄지손가락 들기 제스처 요청을 제출할 수 있습니다.

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

LazyLoadTest 프로젝트에서 RCL에 대한 프로젝트 참조를 GrantImaharaRobotControls 만듭니다.

  • Visual Studio: 프로젝트를 마우스 오른쪽 단추로 클릭하고 LazyLoadTest 프로젝트 참조 추가>를 선택하여 RCL에 대한 프로젝트 참조를 GrantImaharaRobotControls 추가합니다.
  • Visual Studio Code/.NET CLI: 프로젝트 폴더의 명령 셸에서 dotnet add reference {PATH}를 실행합니다. {PATH} 자리 표시자는 RCL 프로젝트 경로입니다.

LazyLoadTest 앱의 프로젝트 파일(.csproj)에 지연 로드를 위한 RCL의 어셈블리를 지정합니다.

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

다음 Router 구성 요소는 사용자가 /robot으로 이동할 때 GrantImaharaRobotControls.{FILE EXTENSION} 어셈블리가 로드되는 것을 보여 줍니다. 앱의 기본 App 구성 요소를 다음 App 구성 요소로 바꿉니다.

페이지 전환 중에 <Navigating> 요소를 사용하여 스타일이 지정된 메시지가 사용자에게 표시됩니다. 자세한 내용은 <Navigating> 콘텐츠와의 사용자 상호 작용 섹션을 참조하세요.

어셈블리가 AdditionalAssemblies에 할당되어 라우터가 어셈블리를 검색하여 라우팅 가능한 구성 요소를 찾게 되어 Robot 구성 요소를 찾습니다. Robot 구성 요소의 경로가 앱의 경로 컬렉션에 추가됩니다. 자세한 내용은 ASP.NET Core Blazor 라우팅 및 탐색 문서와 이 문서의 라우팅 가능한 구성 요소를 포함하는 어셈블리 섹션을 참조하세요.

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

앱을 빌드하고 실행합니다.

RCL의 Robot 구성 요소가 요청 /robotGrantImaharaRobotControls.{FILE EXTENSION} 되면 어셈블리가 로드되고 Robot 구성 요소가 렌더링됩니다. 브라우저 개발자 도구의 네트워크 탭에서 어셈블리 로드를 검사할 수 있습니다.

문제 해결

  • 이전 탐색의 구성 요소 렌더링처럼 예기치 않은 렌더링이 발생하면 취소 토큰이 설정된 경우 코드에서 throw하는지 확인합니다.
  • 앱 시작 시 지연 로드를 위해 구성된 어셈블리가 예기치 않게 로드되는 경우 프로젝트 파일에서 어셈블리가 지연 로드되도록 표시되었는지 확인합니다.

참고 항목

지연 로드된 어셈블리에서 형식을 로드할 때 알려진 문제가 있습니다. 자세한 내용은 Blazor WebAssembly lazy loading assemblies not working when using @ref attribute in the component (dotnet/aspnetcore #29342)를 참조하세요.

추가 리소스