ASP.NET Core Blazor WebAssembly의 어셈블리 지연 로드
참고 항목
이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 9 버전을 참조 하세요.
Important
이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.
현재 릴리스는 이 문서의 .NET 9 버전을 참조 하세요.
Blazor WebAssembly어셈블리가 필요할 때까지 개발자가 만든 앱 어셈블리를 로드하기 위해 대기하여 앱 시작 성능을 향상시킬 수 있습니다. 이를 지연 로드라고 합니다.
이 문서의 초기 섹션에서는 앱 구성을 다룹니다. 작동하는 데모는 이 문서의 끝부분에 있는 전체 예제 섹션을 참조하세요.
이 문서는 Blazor WebAssembly 앱에만 적용됩니다. 어셈블리 지연 로드는 서버 렌더링 앱이 클라이언트에 어셈블리를 다운로드하지 않으므로 서버 쪽 앱에 도움이 되지 않습니다.
지연 로드는 핵심 런타임 어셈블리에 사용해서는 안 됩니다. 이 어셈블리는 게시 시 잘리고 앱이 로드될 때 클라이언트에서 사용할 수 없습니다.
어셈블리 파일의 파일 확장자 자리 표시자({FILE EXTENSION}
)
어셈블리 파일은 파일 확장자를 사용하는 .NET 어셈블리 에 웹빌 패키징 형식을 .wasm
사용합니다.
아티클 전체에서 {FILE EXTENSION}
자리 표시자는 "wasm
"를 나타냅니다.
어셈블리 파일은 파일 확장자를 사용하는 DLL(동적 연결 라이브러리)을 기반으로 합니다 .dll
.
아티클 전체에서 {FILE EXTENSION}
자리 표시자는 "dll
"를 나타냅니다.
프로젝트 파일 구성
.csproj
항목을 사용하여 앱의 프로젝트 파일(BlazorWebAssemblyLazyLoad
)에서 어셈블리를 지연 로드로 표시합니다. 파일 확장명에서 어셈블리 이름을 사용합니다.
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 WebAssembly 섹션의 지연 로드 어셈블리에서 다룹니다.
Blazor의 Router 구성 요소는 Blazor가 라우팅 가능한 구성 요소를 검색하는 어셈블리를 지정하며 사용자가 탐색하는 경로의 구성 요소를 렌더링하는 작업도 담당합니다.
Router 구성 요소의 OnNavigateAsync
메서드는 지연 로드와 함께 사용되어 사용자가 요청하는 엔드포인트에 대한 올바른 어셈블리를 로드합니다.
OnNavigateAsync로 로드할 어셈블리를 결정하는 논리는 LazyAssemblyLoader 내부에 구현됩니다. 이 논리를 구성하는 방법에 대한 옵션은 다음과 같습니다.
- OnNavigateAsync 메서드 내의 조건부 검사입니다.
- 구성 요소에 삽입되거나 구성 요소의 코드 내에서 구현된 어셈블리 이름에 경로를 매핑하는 조회 테이블입니다.
다음 예제에서
- 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);
}
}
}
참고 항목
ASP.NET Core 5.0.1 릴리스 및 추가 5.x 릴리스부터 Router
구성 요소에는 PreferExactMatches
로 설정된 @true
매개 변수가 포함됩니다. 자세한 내용은 ASP.NET Core 3.1에서 5.0으로 마이그레이션을 참조하세요.
라우팅 가능한 구성 요소를 포함하는 어셈블리
어셈블리 목록에 라우팅 가능한 구성 요소가 포함되어 있으면 지정된 경로에 대한 어셈블리 목록이 Router 구성 요소의 AdditionalAssemblies 컬렉션에 전달됩니다.
다음 예제에서
-
의 <Assembly>
lazyLoadedAssemblies
는 어셈블리 목록을 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);
}
}
}
참고 항목
ASP.NET Core 5.0.1 릴리스 및 추가 5.x 릴리스부터 Router
구성 요소에는 PreferExactMatches
로 설정된 @true
매개 변수가 포함됩니다. 자세한 내용은 ASP.NET Core 3.1에서 5.0으로 마이그레이션을 참조하세요.
자세한 내용은 ASP.NET Core Blazor 라우팅 및 탐색을 참조하세요.
<Navigating>
콘텐츠와의 사용자 상호 작용
몇 초 정도 걸릴 수 있는 어셈블리 로드 중에 Router 구성 요소는 라우터의 Navigating 속성을 사용하여 페이지 전환 중임을 사용자에게 나타낼 수 있습니다.
자세한 내용은 ASP.NET Core Blazor 라우팅 및 탐색을 참조하세요.
OnNavigateAsync
에서의 취소 처리
NavigationContext 콜백에 전달되는 OnNavigateAsync 개체에는 새 탐색 이벤트가 발생할 때 설정되는 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 프로젝트에 수동으로 등록합니다.
Program.cs
프로젝트 Server 파일의 맨 위에 Microsoft.AspNetCore.Components.WebAssembly.Services의 네임스페이스를 추가합니다.
using Microsoft.AspNetCore.Components.WebAssembly.Services;
Program.cs
프로젝트의 Server에서 서비스를 등록합니다.
builder.Services.AddScoped<LazyAssemblyLoader>();
Startup.cs
프로젝트 Server 파일의 맨 위에 Microsoft.AspNetCore.Components.WebAssembly.Services의 네임스페이스를 추가합니다.
using Microsoft.AspNetCore.Components.WebAssembly.Services;
프로젝트의 (Startup.ConfigureServices
)Startup.cs
에서 Server 서비스를 등록합니다.
services.AddScoped<LazyAssemblyLoader>();
전체 예제
이 섹션의 데모:
-
GrantImaharaRobotControls.{FILE EXTENSION}
구성 요소(경로 템플릿 Razor을 사용한 )를 포함하는 RCL(Robot.razor
로 로봇 컨트롤 어셈블리(/robot
)를 만듭니다. - 사용자가
Robot
URL을 요청할 때 RCL의 어셈블리를 지연 로드하여 해당/robot
구성 요소를 렌더링합니다.
클래스 라이브러리 어셈블리의 지연 로드를 Blazor WebAssembly 보여 주는 독립 실행형 Razor 앱을 만듭니다. 프로젝트 이름을 LazyLoadTest
로 지정합니다.
솔루션에 ASP.NET Core 클래스 라이브러리 프로젝트를 추가합니다.
- Visual Studio: 솔루션 탐색기 솔루션 파일을 마우스 오른쪽 단추로 클릭하고 새 프로젝트 추가>를 선택합니다. 새 프로젝트 형식 대화 상자에서 클래스 라이브러리Razor 프로젝트 이름을
GrantImaharaRobotControls
로 지정합니다. 지원 페이지 및 보기 확인란을 선택하지 않습니다. - Visual Studio Code/.NET CLI: 명령 프롬프트에서
dotnet new razorclasslib -o GrantImaharaRobotControls
를 실행합니다. 이-o|--output
옵션은 폴더를 만들고 프로젝트의GrantImaharaRobotControls
이름을 지정합니다.
가상으로 로봇이 엄지손가락 들기 제스처를 수행하게 만드는 HandGesture
메서드를 사용하여 RCL에 ThumbUp
클래스를 만듭니다. 이 메서드는 축의 인수 Left
또는 Right
를 enum
으로 수락합니다. 성공하면 이 메서드는 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> </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> </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> </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 구성 요소는 사용자가 GrantImaharaRobotControls.{FILE EXTENSION}
으로 이동할 때 /robot
어셈블리가 로드되는 것을 보여 줍니다. 앱의 기본 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…</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…</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);
}
}
}
앱을 빌드하고 실행합니다.
RCL의 Robot
구성 요소가 요청 /robot
GrantImaharaRobotControls.{FILE EXTENSION}
되면 어셈블리가 로드되고 Robot
구성 요소가 렌더링됩니다. 브라우저 개발자 도구의 네트워크 탭에서 어셈블리 로드를 검사할 수 있습니다.
문제 해결
- 이전 탐색의 구성 요소 렌더링처럼 예기치 않은 렌더링이 발생하면 취소 토큰이 설정된 경우 코드에서 throw하는지 확인합니다.
- 앱 시작 시 지연 로드를 위해 구성된 어셈블리가 예기치 않게 로드되는 경우 프로젝트 파일에서 어셈블리가 지연 로드되도록 표시되었는지 확인합니다.
참고 항목
지연 로드된 어셈블리에서 형식을 로드할 때 알려진 문제가 있습니다. 자세한 내용은 Blazor WebAssembly lazy loading assemblies not working when using @ref attribute in the component (dotnet/aspnetcore #29342)를 참조하세요.
추가 리소스
ASP.NET Core