Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -14,6 +16,9 @@ namespace Microsoft.Extensions.DependencyInjection;
/// </summary>
public static class WebAssemblyRazorComponentsBuilderExtensions
{
private const string LazyAssemblyLoaderAssemblyName = "Microsoft.AspNetCore.Components.WebAssembly";
private const string LazyAssemblyLoaderTypeName = "Microsoft.AspNetCore.Components.WebAssembly.Services.LazyAssemblyLoader";

/// <summary>
/// Adds services to support rendering interactive WebAssembly components.
/// </summary>
Expand All @@ -25,6 +30,15 @@ public static IRazorComponentsBuilder AddInteractiveWebAssemblyComponents(this I

builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<RenderModeEndpointProvider, WebAssemblyEndpointProvider>());

// Try register LazyAssemblyLoader to prevent crashes during prerendering.
// TODO: Remove this once LazyAssemblyLoader is no longer used.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the TODO please

var lazyAssemblyLoaderType = GetLazyAssemblyLoaderType();

if (lazyAssemblyLoaderType != null)
{
builder.Services.TryAddScoped(lazyAssemblyLoaderType);
}

return builder;
}

Expand All @@ -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;
}
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove todo

AssertServerProjectCanUseLazyAssemblyLoader(GetTargetProject(project));
}

// There won't be a counter page when the 'None' interactivity option is used
var pagesToExclude = interactivityOption is "None"
? BlazorTemplatePages.Counter
Expand Down Expand Up @@ -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";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also check that the class is in the dll

var fullPath = Path.Combine(project.TemplateBuildDir, assemblyName);
var doesExist = File.Exists(fullPath);
Assert.True(doesExist, "Required assembly does not exist");
}
}
Loading