diff --git a/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs b/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs
index 0dfb50ef840a..a55065ca9b45 100644
--- a/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs
+++ b/src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Endpoints.Infrastructure;
@@ -14,6 +16,9 @@ namespace Microsoft.Extensions.DependencyInjection;
///
public static class WebAssemblyRazorComponentsBuilderExtensions
{
+ private const string LazyAssemblyLoaderAssemblyName = "Microsoft.AspNetCore.Components.WebAssembly";
+ private const string LazyAssemblyLoaderTypeName = "Microsoft.AspNetCore.Components.WebAssembly.Services.LazyAssemblyLoader";
+
///
/// Adds services to support rendering interactive WebAssembly components.
///
@@ -25,6 +30,15 @@ public static IRazorComponentsBuilder AddInteractiveWebAssemblyComponents(this I
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton());
+ // Try register LazyAssemblyLoader to prevent crashes during prerendering.
+ // TODO: Remove this once LazyAssemblyLoader is no longer used.
+ var lazyAssemblyLoaderType = GetLazyAssemblyLoaderType();
+
+ if (lazyAssemblyLoaderType != null)
+ {
+ builder.Services.TryAddScoped(lazyAssemblyLoaderType);
+ }
+
return builder;
}
@@ -46,4 +60,18 @@ public static IRazorComponentsBuilder AddAuthenticationStateSerialization(this I
return builder;
}
+
+ [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, LazyAssemblyLoaderTypeName, LazyAssemblyLoaderAssemblyName)]
+ private static Type? GetLazyAssemblyLoaderType()
+ {
+ try
+ {
+ var assembly = Assembly.Load(LazyAssemblyLoaderAssemblyName);
+ return assembly.GetType(LazyAssemblyLoaderTypeName, throwOnError: false);
+ }
+ catch
+ {
+ return null;
+ }
+ }
}
diff --git a/src/ProjectTemplates/test/Templates.Blazor.Tests/BlazorWebTemplateTest.cs b/src/ProjectTemplates/test/Templates.Blazor.Tests/BlazorWebTemplateTest.cs
index dc2cf5b63982..7a63733db354 100644
--- a/src/ProjectTemplates/test/Templates.Blazor.Tests/BlazorWebTemplateTest.cs
+++ b/src/ProjectTemplates/test/Templates.Blazor.Tests/BlazorWebTemplateTest.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
@@ -26,6 +27,18 @@ public async Task BlazorWebTemplate_Works(BrowserKind browserKind, string intera
args: ["-int", interactivityOption],
getTargetProject: GetTargetProject);
+ if (HasClientProject())
+ {
+ // In order to prevent an exception casued by missing LazyAssemblyLoader during pre-rendering,
+ // we are registering it into DI in AddInteractiveWebAssemblyComponents.
+ // To avoid adding new references between assemblies we try to resolve the type during run-time using reflection.
+ // This assert is here to check that the assembly containing LazyAssemblyLoader is actually present in a standard app
+ // created from the Blazor Web template.
+ // See https://github.com/dotnet/aspnetcore/issues/51966.
+ // TODO: Remove this when LazyAssemblyLoader is no longer being used, or the dependency graph changes so reflection is no longer needed.
+ AssertServerProjectCanUseLazyAssemblyLoader(GetTargetProject(project));
+ }
+
// There won't be a counter page when the 'None' interactivity option is used
var pagesToExclude = interactivityOption is "None"
? BlazorTemplatePages.Counter
@@ -92,4 +105,12 @@ private static async Task AssertWebAssemblyCompressionFormatAsync(AspNetProcess
});
Assert.Equal(expectedEncoding, response.Content.Headers.ContentEncoding.Single());
}
+
+ private static void AssertServerProjectCanUseLazyAssemblyLoader(Project project)
+ {
+ var assemblyName = "Microsoft.AspNetCore.Components.WebAssembly.dll";
+ var fullPath = Path.Combine(project.TemplateBuildDir, assemblyName);
+ var doesExist = File.Exists(fullPath);
+ Assert.True(doesExist, "Required assembly does not exist");
+ }
}