Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPranav K <prkrishn@hotmail.com>2020-05-05 19:06:42 +0300
committerGitHub <noreply@github.com>2020-05-05 19:06:42 +0300
commit9e412f4c7f0bf6f0e43db27a17bc938c36160f41 (patch)
treecf74c6fc5e29a73d5a723465655cfd755b9dd661 /src/Components/WebAssembly
parentcc2b64ec5e324f1bf843e608f01b9292a2155b20 (diff)
Do not attempt to load satellite assemblies until after MainAsync has executed (#21476)
WASM runtime does not like it when you attempt to load satellite assemblies for two sets of non-neutral cultures - the first is always loaded. This change defers loading satellite assemblies until after Program.Main has executed and the developer has configured the culture for the application. Fixes https://github.com/dotnet/aspnetcore/issues/21433
Diffstat (limited to 'src/Components/WebAssembly')
-rw-r--r--src/Components/WebAssembly/WebAssembly/src/Hosting/EntrypointInvoker.cs11
-rw-r--r--src/Components/WebAssembly/WebAssembly/src/Hosting/SatelliteResourcesLoader.cs25
-rw-r--r--src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs3
-rw-r--r--src/Components/WebAssembly/WebAssembly/test/Hosting/EntrypointInvokerTest.cs21
-rw-r--r--src/Components/WebAssembly/WebAssembly/test/Hosting/SatelliteResourcesLoaderTest.cs40
-rw-r--r--src/Components/WebAssembly/WebAssembly/test/Hosting/WebAssemblyHostTest.cs2
6 files changed, 9 insertions, 93 deletions
diff --git a/src/Components/WebAssembly/WebAssembly/src/Hosting/EntrypointInvoker.cs b/src/Components/WebAssembly/WebAssembly/src/Hosting/EntrypointInvoker.cs
index 1fe153f17a..5fdea9e41b 100644
--- a/src/Components/WebAssembly/WebAssembly/src/Hosting/EntrypointInvoker.cs
+++ b/src/Components/WebAssembly/WebAssembly/src/Hosting/EntrypointInvoker.cs
@@ -15,19 +15,10 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
// In the future we may want Blazor.start to return something that exposes the possibly-async
// entrypoint result to the JS caller. There's no requirement to do that today, and if we
// do change this it will be non-breaking.
- public static void InvokeEntrypoint(string assemblyName, string[] args)
- => InvokeEntrypoint(assemblyName, args, SatelliteResourcesLoader.Init());
-
- internal static async void InvokeEntrypoint(string assemblyName, string[] args, SatelliteResourcesLoader satelliteResourcesLoader)
+ public static async void InvokeEntrypoint(string assemblyName, string[] args)
{
try
{
- // Emscripten sets up the culture for the application based on the user's language preferences.
- // Before we execute the app's entry point, load satellite assemblies for this culture.
- // We'll allow users to configure their app culture as part of MainAsync. Loading satellite assemblies
- // for the configured culture will happen as part of WebAssemblyHost.RunAsync.
- await satelliteResourcesLoader.LoadCurrentCultureResourcesAsync();
-
var assembly = Assembly.Load(assemblyName);
var entrypoint = FindUnderlyingEntrypoint(assembly);
var @params = entrypoint.GetParameters().Length == 1 ? new object[] { args ?? Array.Empty<string>() } : new object[] { };
diff --git a/src/Components/WebAssembly/WebAssembly/src/Hosting/SatelliteResourcesLoader.cs b/src/Components/WebAssembly/WebAssembly/src/Hosting/SatelliteResourcesLoader.cs
index c4a5c33c68..79f780c584 100644
--- a/src/Components/WebAssembly/WebAssembly/src/Hosting/SatelliteResourcesLoader.cs
+++ b/src/Components/WebAssembly/WebAssembly/src/Hosting/SatelliteResourcesLoader.cs
@@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
-using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Threading.Tasks;
@@ -16,7 +15,6 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
internal const string ReadSatelliteAssemblies = "window.Blazor._internal.readSatelliteAssemblies";
private readonly WebAssemblyJSRuntimeInvoker _invoker;
- private CultureInfo _previousCulture;
// For unit testing.
internal SatelliteResourcesLoader(WebAssemblyJSRuntimeInvoker invoker)
@@ -24,28 +22,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
_invoker = invoker;
}
- public static SatelliteResourcesLoader Instance { get; private set; }
-
- public static SatelliteResourcesLoader Init()
- {
- Debug.Assert(Instance is null, "Init should not be called multiple times.");
-
- Instance = new SatelliteResourcesLoader(WebAssemblyJSRuntimeInvoker.Instance);
- return Instance;
- }
-
- public ValueTask LoadCurrentCultureResourcesAsync()
- {
- if (_previousCulture != CultureInfo.CurrentCulture)
- {
- _previousCulture = CultureInfo.CurrentCulture;
- return LoadSatelliteAssembliesForCurrentCultureAsync();
- }
-
- return default;
- }
-
- protected virtual async ValueTask LoadSatelliteAssembliesForCurrentCultureAsync()
+ public virtual async ValueTask LoadCurrentCultureResourcesAsync()
{
var culturesToLoad = GetCultures(CultureInfo.CurrentCulture);
diff --git a/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs b/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs
index 308d698c8f..c81dd2ac28 100644
--- a/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs
+++ b/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs
@@ -6,6 +6,7 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Infrastructure;
using Microsoft.AspNetCore.Components.WebAssembly.Rendering;
+using Microsoft.AspNetCore.Components.WebAssembly.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -58,7 +59,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
/// </summary>
public IServiceProvider Services => _scope.ServiceProvider;
- internal SatelliteResourcesLoader SatelliteResourcesLoader { get; set; } = SatelliteResourcesLoader.Instance;
+ internal SatelliteResourcesLoader SatelliteResourcesLoader { get; set; } = new SatelliteResourcesLoader(WebAssemblyJSRuntimeInvoker.Instance);
/// <summary>
/// Disposes the host asynchronously.
diff --git a/src/Components/WebAssembly/WebAssembly/test/Hosting/EntrypointInvokerTest.cs b/src/Components/WebAssembly/WebAssembly/test/Hosting/EntrypointInvokerTest.cs
index aef12b3c7f..eafc042993 100644
--- a/src/Components/WebAssembly/WebAssembly/test/Hosting/EntrypointInvokerTest.cs
+++ b/src/Components/WebAssembly/WebAssembly/test/Hosting/EntrypointInvokerTest.cs
@@ -2,15 +2,12 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
-using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.Loader;
using System.Threading.Tasks;
-using Microsoft.AspNetCore.Components.WebAssembly.Services;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
-using Moq;
using Xunit;
namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
@@ -36,7 +33,7 @@ static " + returnType + @" Main(" + paramsDecl + @")
}", out var didMainExecute);
// Act
- EntrypointInvoker.InvokeEntrypoint(assembly.FullName, new string[] { }, new TestSatelliteResourcesLoader());
+ EntrypointInvoker.InvokeEntrypoint(assembly.FullName, new string[] { });
// Assert
Assert.True(didMainExecute());
@@ -66,7 +63,7 @@ static async Task" + returnTypeGenericParam + @" Main(" + paramsDecl + @")
// Act/Assert 1: Waits for task
// The fact that we're not blocking here proves that we're not executing the
// metadata-declared entrypoint, as that would block
- EntrypointInvoker.InvokeEntrypoint(assembly.FullName, new string[] { }, new TestSatelliteResourcesLoader());
+ EntrypointInvoker.InvokeEntrypoint(assembly.FullName, new string[] { });
Assert.False(didMainExecute());
// Act/Assert 2: Continues
@@ -91,7 +88,7 @@ public static void Main()
// to handle the exception. We can't assert about what it does here, because that
// would involve capturing console output, which isn't safe in unit tests. Instead
// we'll check this in E2E tests.
- EntrypointInvoker.InvokeEntrypoint(assembly.FullName, new string[] { }, new TestSatelliteResourcesLoader());
+ EntrypointInvoker.InvokeEntrypoint(assembly.FullName, new string[] { });
Assert.True(didMainExecute());
}
@@ -110,7 +107,7 @@ public static async Task Main()
}", out var didMainExecute);
// Act/Assert 1: Waits for task
- EntrypointInvoker.InvokeEntrypoint(assembly.FullName, new string[] { }, new TestSatelliteResourcesLoader());
+ EntrypointInvoker.InvokeEntrypoint(assembly.FullName, new string[] { });
Assert.False(didMainExecute());
// Act/Assert 2: Continues
@@ -152,15 +149,5 @@ namespace SomeApp
return assembly;
}
-
- private class TestSatelliteResourcesLoader : SatelliteResourcesLoader
- {
- internal TestSatelliteResourcesLoader()
- : base(WebAssemblyJSRuntimeInvoker.Instance)
- {
- }
-
- protected override ValueTask LoadSatelliteAssembliesForCurrentCultureAsync() => default;
- }
}
}
diff --git a/src/Components/WebAssembly/WebAssembly/test/Hosting/SatelliteResourcesLoaderTest.cs b/src/Components/WebAssembly/WebAssembly/test/Hosting/SatelliteResourcesLoaderTest.cs
index d541d404dc..c4bb704bb4 100644
--- a/src/Components/WebAssembly/WebAssembly/test/Hosting/SatelliteResourcesLoaderTest.cs
+++ b/src/Components/WebAssembly/WebAssembly/test/Hosting/SatelliteResourcesLoaderTest.cs
@@ -70,45 +70,5 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
// Assert
invoker.Verify(i => i.InvokeUnmarshalled<object, object, object, object[]>(ReadSatelliteAssemblies, null, null, null), Times.Never());
}
-
- [Fact]
- public async Task LoadCurrentCultureResourcesAsync_AttemptsToReadAssemblies_IfCultureIsChangedBetweenInvocation()
- {
- // Arrange
- using var cultureReplacer = new CultureReplacer("en-GB");
- var invoker = new Mock<WebAssemblyJSRuntimeInvoker>();
- invoker.Setup(i => i.InvokeUnmarshalled<string[], object, object, Task<object>>(GetSatelliteAssemblies, It.IsAny<string[]>(), null, null))
- .Returns(Task.FromResult<object>(0))
- .Verifiable();
-
- var loader = new SatelliteResourcesLoader(invoker.Object);
-
- // Act
- await loader.LoadCurrentCultureResourcesAsync();
- CultureInfo.CurrentCulture = new CultureInfo("fr-fr");
- await loader.LoadCurrentCultureResourcesAsync();
-
- invoker.Verify(i => i.InvokeUnmarshalled<object, object, object, Task<object>>(GetSatelliteAssemblies, It.IsAny<string[]>(), null, null),
- Times.Exactly(2));
- }
-
- [Fact]
- public async Task LoadCurrentCultureResourcesAsync_NoOps_WhenInvokedSecondTime_WithSameCulture()
- {
- // Arrange
- using var cultureReplacer = new CultureReplacer("en-GB");
- var invoker = new Mock<WebAssemblyJSRuntimeInvoker>();
- invoker.Setup(i => i.InvokeUnmarshalled<string[], object, object, Task<object>>(GetSatelliteAssemblies, It.IsAny<string[]>(), null, null))
- .Returns(Task.FromResult<object>(0));;
-
- var loader = new SatelliteResourcesLoader(invoker.Object);
-
- // Act
- await loader.LoadCurrentCultureResourcesAsync();
- await loader.LoadCurrentCultureResourcesAsync();
-
- invoker.Verify(i => i.InvokeUnmarshalled<object, object, object, Task<object>>(GetSatelliteAssemblies, It.IsAny<string[]>(), null, null),
- Times.Once());
- }
}
}
diff --git a/src/Components/WebAssembly/WebAssembly/test/Hosting/WebAssemblyHostTest.cs b/src/Components/WebAssembly/WebAssembly/test/Hosting/WebAssemblyHostTest.cs
index c827250134..71c273c74c 100644
--- a/src/Components/WebAssembly/WebAssembly/test/Hosting/WebAssemblyHostTest.cs
+++ b/src/Components/WebAssembly/WebAssembly/test/Hosting/WebAssemblyHostTest.cs
@@ -99,7 +99,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
{
}
- protected override ValueTask LoadSatelliteAssembliesForCurrentCultureAsync() => default;
+ public override ValueTask LoadCurrentCultureResourcesAsync() => default;
}
}
}