Skip to content

Commit de0738a

Browse files
committed
Configure lazy-loaded assemblies in WebAssemblyLazyLoadDefinition
1 parent ec5f407 commit de0738a

File tree

12 files changed

+71
-54
lines changed

12 files changed

+71
-54
lines changed

src/Components/Components/src/NavigationManager.cs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5-
using System.Collections.Generic;
6-
using System.Reflection;
7-
using System.Threading.Tasks;
85
using Microsoft.AspNetCore.Components.Routing;
96

107
namespace Microsoft.AspNetCore.Components
@@ -30,7 +27,6 @@ public event EventHandler<LocationChangedEventArgs> LocationChanged
3027
_locationChanged -= value;
3128
}
3229
}
33-
public Func<string, List<string>>? OnNavigate { get; set; }
3430

3531
private EventHandler<LocationChangedEventArgs>? _locationChanged;
3632

@@ -203,11 +199,10 @@ internal static string NormalizeBaseUri(string baseUri)
203199
/// <summary>
204200
/// Triggers the <see cref="LocationChanged"/> event with the current URI value.
205201
/// </summary>
206-
protected async Task NotifyLocationChanged(bool isInterceptedLink)
202+
protected void NotifyLocationChanged(bool isInterceptedLink)
207203
{
208204
try
209205
{
210-
await BeforeLocationChangeAsync();
211206
_locationChanged?.Invoke(this, new LocationChangedEventArgs(_uri!, isInterceptedLink));
212207
}
213208
catch (Exception ex)
@@ -216,8 +211,6 @@ protected async Task NotifyLocationChanged(bool isInterceptedLink)
216211
}
217212
}
218213

219-
public virtual Task BeforeLocationChangeAsync() => Task.CompletedTask;
220-
221214
private void AssertInitialized()
222215
{
223216
if (!_isInitialized)

src/Components/Components/src/Routing/Router.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ static readonly ReadOnlyDictionary<string, object> _emptyParametersDictionary
5656
/// </summary>
5757
[Parameter] public RenderFragment<RouteData> Found { get; set; }
5858

59-
[Parameter] public Func<string, List<string>> OnNavigate { get; set; }
60-
6159
private RouteTable Routes { get; set; }
6260

6361
/// <inheritdoc />
@@ -71,7 +69,7 @@ public void Attach(RenderHandle renderHandle)
7169
}
7270

7371
/// <inheritdoc />
74-
public async Task SetParametersAsync(ParameterView parameters)
72+
public Task SetParametersAsync(ParameterView parameters)
7573
{
7674
parameters.SetParameterProperties(this);
7775

@@ -95,16 +93,11 @@ public async Task SetParametersAsync(ParameterView parameters)
9593
throw new InvalidOperationException($"The {nameof(Router)} component requires a value for the parameter {nameof(NotFound)}.");
9694
}
9795

98-
if (OnNavigate != null) {
99-
NavigationManager.OnNavigate = OnNavigate;
100-
}
101-
102-
await NavigationManager.BeforeLocationChangeAsync();
103-
10496

10597
var assemblies = AdditionalAssemblies == null ? new[] { AppAssembly } : new[] { AppAssembly }.Concat(AdditionalAssemblies);
10698
Routes = RouteTableFactory.Create(assemblies);
10799
Refresh(isNavigationIntercepted: false);
100+
return Task.CompletedTask;
108101
}
109102

110103
/// <inheritdoc />

src/Components/Web.JS/dist/Release/blazor.webassembly.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,11 @@ function createEmscriptenModuleInstance(resourceLoader: WebAssemblyResourceLoade
296296
if (dynamicAssemblies) {
297297
const resourcePromises = Promise.all(assembliesToLoad
298298
.filter(assembly => dynamicAssemblies.hasOwnProperty(assembly))
299-
.map(assembly => resourceLoader.loadResource(assembly, `_framework/_bin/${assembly}`, dynamicAssemblies[assembly], 'assembly'))
299+
.map(assembly => resourceLoader.loadResource(assembly, `_framework/${assembly}`, dynamicAssemblies[assembly], 'assembly'))
300300
.map(async resource => (await resource.response).arrayBuffer()));
301301

302302
return BINDING.js_to_mono_obj(
303303
resourcePromises.then(resourcesToLoad => {
304-
console.log(`resourcesToLoad: ${resourcesToLoad}`)
305304
if (resourcesToLoad.length) {
306305
window['Blazor']._internal.readDynamicAssemblies = () => {
307306
const array = BINDING.mono_obj_array_new(resourcesToLoad.length);

src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,11 @@ public void ConfigureContainer<TBuilder>(IServiceProviderFactory<TBuilder> facto
168168
};
169169
}
170170

171+
public void SetLazyLoadDefinition(WebAssemblyLazyLoadDefinition lazyLoadDefinition)
172+
{
173+
WebAssemblyNavigationManager.Instance.LazyLoadDefinition = lazyLoadDefinition;
174+
}
175+
171176
/// <summary>
172177
/// Builds a <see cref="WebAssemblyHost"/> instance based on the configuration of this builder.
173178
/// </summary>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Reflection;
4+
using System.Text;
5+
6+
namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
7+
{
8+
public class WebAssemblyLazyLoadDefinition
9+
{
10+
public WebAssemblyLazyLoadDefinition()
11+
{
12+
LazyLoadMappings = new Dictionary<string, IEnumerable<string>>();
13+
}
14+
15+
public WebAssemblyLazyLoadDefinition(Dictionary<string, IEnumerable<string>> _lazyLoadMappings)
16+
{
17+
LazyLoadMappings = _lazyLoadMappings;
18+
}
19+
20+
public void AddRouteDefinition(string route, IEnumerable<string> assemblies)
21+
{
22+
LazyLoadMappings[route] = assemblies;
23+
}
24+
25+
public IEnumerable<string> GetLazyAssembliesForRoute(string uri)
26+
{
27+
IEnumerable<string> assembliesToLoad;
28+
29+
if (!LazyLoadMappings.TryGetValue(uri, out assembliesToLoad))
30+
{
31+
return null;
32+
}
33+
return assembliesToLoad;
34+
}
35+
36+
public Dictionary<string, IEnumerable<string>> LazyLoadMappings { get; }
37+
}
38+
}

src/Components/WebAssembly/WebAssembly/src/Services/WebAssemblyNavigationManager.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Linq;
67
using System.Reflection;
78
using System.Threading.Tasks;
89
using Microsoft.AspNetCore.Components.Routing;
10+
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
911
using Interop = Microsoft.AspNetCore.Components.Web.BrowserNavigationManagerInterop;
1012

1113
namespace Microsoft.AspNetCore.Components.WebAssembly.Services
@@ -20,15 +22,18 @@ internal class WebAssemblyNavigationManager : NavigationManager
2022
/// </summary>
2123
public static WebAssemblyNavigationManager Instance { get; set; }
2224

25+
public WebAssemblyLazyLoadDefinition LazyLoadDefinition { get; set; }
26+
2327
public WebAssemblyNavigationManager(string baseUri, string uri)
2428
{
2529
Initialize(baseUri, uri);
2630
}
2731

28-
public Task SetLocation(string uri, bool isInterceptedLink)
32+
public async Task SetLocation(string uri, bool isInterceptedLink)
2933
{
3034
Uri = uri;
31-
return NotifyLocationChanged(isInterceptedLink);
35+
await BeforeLocationChangeAsync();
36+
NotifyLocationChanged(isInterceptedLink);
3237
}
3338

3439
/// <inheritdoc />
@@ -42,15 +47,16 @@ protected override void NavigateToCore(string uri, bool forceLoad)
4247
DefaultWebAssemblyJSRuntime.Instance.Invoke<object>(Interop.NavigateTo, uri, forceLoad);
4348
}
4449

45-
public override async Task BeforeLocationChangeAsync()
50+
public async Task BeforeLocationChangeAsync()
4651
{
47-
if (OnNavigate == null) {
52+
if (LazyLoadDefinition == null) {
4853
return;
4954
}
5055

51-
var assembliesToLoad = OnNavigate(Uri);
56+
var path = Uri.Replace(BaseUri, "");
57+
var assembliesToLoad = LazyLoadDefinition.GetLazyAssembliesForRoute(path);
5258

53-
if (assembliesToLoad.Count == 0)
59+
if (assembliesToLoad == null)
5460
{
5561
return;
5662
}
@@ -72,9 +78,9 @@ public override async Task BeforeLocationChangeAsync()
7278
null,
7379
null);
7480

75-
for (var i = 0; i < assemblies.Length; i++)
81+
foreach (byte[] assembly in assemblies)
7682
{
77-
Assembly.Load((byte[])assemblies[i]);
83+
Assembly.Load(assembly);
7884
}
7985
}
8086
}

src/Components/test/E2ETest/Tests/RoutingTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ public void CanLazyLoadOnRouteChange()
527527
{
528528
// Navigate to a page without any lazy-loaded dependencies
529529
SetUrlViaPushState("/");
530-
var app = Browser.MountTestComponent<TestRouterWithDynamicAssembly>();
530+
var app = Browser.MountTestComponent<TestRouter>();
531531

532532
// Ensure that we haven't requested the lazy loaded assembly
533533
Assert.False(HasLoadedAssembly("Newtonsoft.Json.dll"));
@@ -551,7 +551,7 @@ public void CanLazyLoadOnFirstVisit()
551551
{
552552
// Navigate to a page with lazy loaded assemblies for the first time
553553
SetUrlViaPushState("/WithDynamicAssembly");
554-
var app = Browser.MountTestComponent<TestRouterWithDynamicAssembly>();
554+
var app = Browser.MountTestComponent<TestRouter>();
555555
var button = app.FindElement(By.Id("use-package-button"));
556556

557557
// We should have requested the DLL

src/Components/test/testassets/BasicTestApp/BasicTestApp.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
</ItemGroup>
3333

3434
<ItemGroup>
35-
<BlazorWebAssemblyLazyLoad Include="Newtonsoft.Json.dll" />
35+
<BlazorWebAssemblyLazyLoad Include="Newtonsoft.Json" />
3636
</ItemGroup>
3737

3838
</Project>

src/Components/test/testassets/BasicTestApp/Index.razor

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@
7070
<option value="BasicTestApp.RouterTest.NavigationManagerComponent">NavigationManager Test</option>
7171
<option value="BasicTestApp.RouterTest.TestRouter">Router</option>
7272
<option value="BasicTestApp.RouterTest.TestRouterWithAdditionalAssembly">Router with additional assembly</option>
73-
<option value="BasicTestApp.RouterTest.TestRouterWithDynamicAssembly">Router with dynamic assembly</option>
7473
<option value="BasicTestApp.StringComparisonComponent">StringComparison</option>
7574
<option value="BasicTestApp.SvgComponent">SVG</option>
7675
<option value="BasicTestApp.SvgWithChildComponent">SVG with child component</option>

src/Components/test/testassets/BasicTestApp/Program.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using Microsoft.Extensions.Logging;
1919
using Microsoft.Extensions.Logging.Configuration;
2020
using Microsoft.JSInterop;
21+
using System.Collections.Generic;
2122

2223
namespace BasicTestApp
2324
{
@@ -30,6 +31,11 @@ public static async Task Main(string[] args)
3031
var builder = WebAssemblyHostBuilder.CreateDefault(args);
3132
builder.RootComponents.Add<Index>("root");
3233

34+
// Set lazy-load definition for a single path
35+
WebAssemblyLazyLoadDefinition lazyLoadDefinition = new WebAssemblyLazyLoadDefinition();
36+
lazyLoadDefinition.AddRouteDefinition("WithDynamicAssembly", new List<string>() { "Newtonsoft.Json.dll" });
37+
builder.SetLazyLoadDefinition(lazyLoadDefinition);
38+
3339
builder.Services.AddSingleton(new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
3440
builder.Services.AddSingleton<AuthenticationStateProvider, ServerAuthenticationStateProvider>();
3541
builder.Services.AddAuthorizationCore(options =>

src/Components/test/testassets/BasicTestApp/RouterTest/TestRouterWithDynamicAssembly.razor

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)