Skip to content

Commit

Permalink
- Added loading of debug symbols
Browse files Browse the repository at this point in the history
  • Loading branch information
RonSijm committed Apr 6, 2024
1 parent 652b6a8 commit 23f8b42
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 91 deletions.
2 changes: 1 addition & 1 deletion BuildSettings/NuGetVersioning.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<PropertyGroup>
<Authors>Ron Sijm</Authors>
<Company>Ron Sijm</Company>
<VersionPrefix>1.2.0</VersionPrefix>
<VersionPrefix>1.3.0</VersionPrefix>
</PropertyGroup>
</Project>
46 changes: 1 addition & 45 deletions Examples/RonSijm.Demo.Blazyload.Host/App.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@inject BlazyAssemblyLoader BlazyAssemblyLoader;
@inject IAssemblyLoader BlazyAssemblyLoader;

<Router AppAssembly="@typeof(App).Assembly" OnNavigateAsync="@OnNavigateAsync" AdditionalAssemblies="@_lazyLoadedAssemblies">

Expand All @@ -13,48 +13,4 @@
</LayoutView>
</NotFound>
</Router>

@code {
private readonly List<Assembly> _lazyLoadedAssemblies = new();

private async Task OnNavigateAsync(NavigationContext args)
{
try
{
if (args.Path == "fetchdata1")
{
var assemblies = await BlazyAssemblyLoader.LoadAssemblyAsync("RonSijm.Demo.Blazyload.WeatherLib1.wasm");
_lazyLoadedAssemblies.AddRange(assemblies);
}
else if (args.Path == "fetchdata2")
{
var assemblies = await BlazyAssemblyLoader.LoadAssemblyAsync("RonSijm.Demo.Blazyload.WeatherLib2.wasm");
_lazyLoadedAssemblies.AddRange(assemblies);
}
else if (args.Path == "fetchdata3")
{
var assemblies = await BlazyAssemblyLoader.LoadAssemblyAsync("RonSijm.Demo.Blazyload.WeatherLib3.wasm");
_lazyLoadedAssemblies.AddRange(assemblies);
}
else if (args.Path == "fetchdata4")
{
var assemblies = await BlazyAssemblyLoader.LoadAssemblyAsync("RonSijm.Demo.Blazyload.WeatherLib4.Page.wasm");
_lazyLoadedAssemblies.AddRange(assemblies);
}
else if (args.Path == "fetchdataOptionalNull")
{
var assemblies = await BlazyAssemblyLoader.LoadAssemblyAsync("RonSijm.Demo.Blazyload.WeatherLibOptionalNull.wasm");
_lazyLoadedAssemblies.AddRange(assemblies);
}
else if (args.Path == "fetchdataOptionalNotNull")
{
var assemblies = await BlazyAssemblyLoader.LoadAssemblyAsync("RonSijm.Demo.Blazyload.WeatherLibOptionalNotNull.wasm");
_lazyLoadedAssemblies.AddRange(assemblies);
}
}
catch (Exception)
{
// Do Nothing
}
}
}
50 changes: 50 additions & 0 deletions Examples/RonSijm.Demo.Blazyload.Host/App.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Microsoft.AspNetCore.Components.Routing;
using System.Reflection;

namespace RonSijm.Demo.Blazyload.Host;

public partial class App
{
private readonly List<Assembly> _lazyLoadedAssemblies = new();

private async Task OnNavigateAsync(NavigationContext args)
{
try
{
if (args.Path == "fetchdata1")
{
var assemblies = await BlazyAssemblyLoader.LoadAssemblyAsync("RonSijm.Demo.Blazyload.WeatherLib1.wasm");
_lazyLoadedAssemblies.AddRange(assemblies);
}
else if (args.Path == "fetchdata2")
{
var assemblies = await BlazyAssemblyLoader.LoadAssemblyAsync("RonSijm.Demo.Blazyload.WeatherLib2.wasm");
_lazyLoadedAssemblies.AddRange(assemblies);
}
else if (args.Path == "fetchdata3")
{
var assemblies = await BlazyAssemblyLoader.LoadAssemblyAsync("RonSijm.Demo.Blazyload.WeatherLib3.wasm");
_lazyLoadedAssemblies.AddRange(assemblies);
}
else if (args.Path == "fetchdata4")
{
var assemblies = await BlazyAssemblyLoader.LoadAssemblyAsync("RonSijm.Demo.Blazyload.WeatherLib4.Page.wasm");
_lazyLoadedAssemblies.AddRange(assemblies);
}
else if (args.Path == "fetchdataOptionalNull")
{
var assemblies = await BlazyAssemblyLoader.LoadAssemblyAsync("RonSijm.Demo.Blazyload.WeatherLibOptionalNull.wasm");
_lazyLoadedAssemblies.AddRange(assemblies);
}
else if (args.Path == "fetchdataOptionalNotNull")
{
var assemblies = await BlazyAssemblyLoader.LoadAssemblyAsync("RonSijm.Demo.Blazyload.WeatherLibOptionalNotNull.wasm");
_lazyLoadedAssemblies.AddRange(assemblies);
}
}
catch (Exception)
{
// Do Nothing
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
@page "/fetchdata3"
@inject IWeatherResolver WeatherResolver

<h1>Weather forecast</h1>

Expand Down Expand Up @@ -32,13 +31,4 @@ else
}
</tbody>
</table>
}

@code {
private WeatherForecast[] _forecasts;

protected override async Task OnInitializedAsync()
{
_forecasts = await WeatherResolver.GetWeather();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Microsoft.AspNetCore.Components;

namespace RonSijm.Demo.Blazyload.WeatherLib3.Pages;

public partial class FetchData
{
[Inject]
public IWeatherResolver WeatherResolver { get; set; }

private WeatherForecast[] _forecasts;

protected override async Task OnInitializedAsync()
{
_forecasts = await WeatherResolver.GetWeather();
}
}
9 changes: 0 additions & 9 deletions RonSijm.Blazyload.WithExamples.sln
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RonSijm.Demo.Blazyload.Weat
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RonSijm.Demo.Blazyload.Host", "Examples\RonSijm.Demo.Blazyload.Host\RonSijm.Demo.Blazyload.Host.csproj", "{F250D926-3859-4CFD-94C7-F7D66DEFCB88}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{01C04B24-3201-49A7-B804-192E29F46968}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RonSijm.Demo.Blazyload.Host.Tests", "Tests\RonSijm.Demo.Blazyload.Host.Tests\RonSijm.Demo.Blazyload.Host.Tests.csproj", "{C370CA6F-8724-4AC7-96E8-6BF0DA9373CB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CustomPathing", "CustomPathing", "{3DD6A980-A713-4811-BB9A-E64E3C8F0327}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RonSijm.Demo.Blazyload.CustomPathing.Host", "Examples\CustomPathing\RonSijm.Demo.Blazyload.CustomPathing.Host\RonSijm.Demo.Blazyload.CustomPathing.Host.csproj", "{CBDE48B3-CB56-42C1-869A-115109AC508F}"
Expand Down Expand Up @@ -83,10 +79,6 @@ Global
{F250D926-3859-4CFD-94C7-F7D66DEFCB88}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F250D926-3859-4CFD-94C7-F7D66DEFCB88}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F250D926-3859-4CFD-94C7-F7D66DEFCB88}.Release|Any CPU.Build.0 = Release|Any CPU
{C370CA6F-8724-4AC7-96E8-6BF0DA9373CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C370CA6F-8724-4AC7-96E8-6BF0DA9373CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C370CA6F-8724-4AC7-96E8-6BF0DA9373CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C370CA6F-8724-4AC7-96E8-6BF0DA9373CB}.Release|Any CPU.Build.0 = Release|Any CPU
{CBDE48B3-CB56-42C1-869A-115109AC508F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CBDE48B3-CB56-42C1-869A-115109AC508F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CBDE48B3-CB56-42C1-869A-115109AC508F}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -111,7 +103,6 @@ Global
{1C505122-9CD9-4227-9168-BE1AB23B285A} = {37BE4301-22F2-4C22-B36C-EFF2F23B7FC3}
{42BB3515-44AE-4229-B46C-3696F54642AB} = {37BE4301-22F2-4C22-B36C-EFF2F23B7FC3}
{F250D926-3859-4CFD-94C7-F7D66DEFCB88} = {82F74E52-8C18-4235-A492-DDE7D47BF530}
{C370CA6F-8724-4AC7-96E8-6BF0DA9373CB} = {01C04B24-3201-49A7-B804-192E29F46968}
{3DD6A980-A713-4811-BB9A-E64E3C8F0327} = {6CA40C0F-7403-483B-973E-AFB6FA50D087}
{CBDE48B3-CB56-42C1-869A-115109AC508F} = {3DD6A980-A713-4811-BB9A-E64E3C8F0327}
{82F74E52-8C18-4235-A492-DDE7D47BF530} = {6CA40C0F-7403-483B-973E-AFB6FA50D087}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
<Import Project="..\..\BuildSettings\NuGetVersioning.props" />

<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Title>RonSijm.Blazyload.Library</Title>
<Description>The client components of RonSijm.Blazyload</Description>
Expand Down
63 changes: 40 additions & 23 deletions src/RonSijm.Blazyload/Features/DIComponents/BlazyAssemblyLoader.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// ReSharper disable global EventNeverSubscribedTo.Global - Justification: Used by library consumers
// ReSharper disable global UnusedMember.Global - Justification: Used by library consumers

using System.Diagnostics;
using System.Net.Http.Json;
using Microsoft.AspNetCore.Components;
using RonSijm.Blazyload.Features.DIComponents.Models;

namespace RonSijm.Blazyload.Features.DIComponents;

public class BlazyAssemblyLoader(BlazyServiceProvider blazyServiceProvider, NavigationManager navigationManager)
public class BlazyAssemblyLoader(BlazyServiceProvider blazyServiceProvider, NavigationManager navigationManager) : IAssemblyLoader
{
private HashSet<string> _loadedAssemblies = new();

Expand Down Expand Up @@ -73,7 +74,6 @@ private async Task<List<Assembly>> LoadAssembliesAsync(IEnumerable<string> assem
var referenceAssemblies = assembly.GetReferencedAssemblies();
var assemblyNames = referenceAssemblies.Select(referenceAssembly => $"{referenceAssembly.Name}.wasm");

// "Oh no! recursion! ಠ_ಠ" - Possibly implement trampoline pattern if this causes issues
var cascadeResults = await LoadAssembliesAsync(assemblyNames, true);
}
}
Expand Down Expand Up @@ -131,45 +131,62 @@ private async Task<Assembly[]> LoadAssembliesWithByOptions(List<(string assembly

using var client = new HttpClient();

foreach (var assemblyToLoad in assembliesToLoad)
foreach (var (assemblyToLoad, options) in assembliesToLoad)
{
var dllLocation = GetDllLocationFromOptions(assemblyToLoad);
var loadedAssemblyBytes = await LoadFileAssembly(assemblyToLoad, options, client);

var request = new HttpRequestMessage(HttpMethod.Get, $"{dllLocation}{assemblyToLoad.assemblyToLoad}");
Stream loadedSymbols = null;

if (assemblyToLoad.options is { HttpHandler: { } })
if (Debugger.IsAttached)
{
var isSuccess = assemblyToLoad.options.HttpHandler.Invoke(assemblyToLoad.assemblyToLoad, request, assemblyToLoad.options);
// Dotnet6+7 use a DLL, Dotnet8 changed it to .wasm
var symbolsToLoad = assemblyToLoad.Replace(".wasm", ".pdb").Replace(".dll", ".pdb");
loadedSymbols = await LoadFileAssembly(symbolsToLoad, options, client);
}

if (!isSuccess)
{
// HttpHandler indicated we can't process this
continue;
}
if (loadedAssemblyBytes != null)
{
var assembly = AssemblyLoadContext.Default.LoadFromStream(loadedAssemblyBytes, loadedSymbols);
loadedAssemblies.Add(assembly);
}
}

return loadedAssemblies.ToArray();
}

var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
private async Task<Stream> LoadFileAssembly(string assemblyToLoad, BlazyAssemblyOptions options, HttpClient client)
{
var dllLocation = GetDllLocationFromOptions(options);

// TODO: We could add an option to do enable sha- validation
var request = new HttpRequestMessage(HttpMethod.Get, $"{dllLocation}{assemblyToLoad}");

var contentBytes = await response.Content.ReadAsStreamAsync();
var assembly = AssemblyLoadContext.Default.LoadFromStream(contentBytes);
if (options is { HttpHandler: { } })
{
var isSuccess = options.HttpHandler.Invoke(assemblyToLoad, request, options);

loadedAssemblies.Add(assembly);
if (!isSuccess)
{
// HttpHandler indicated we can't process this
return null;
}
}

return loadedAssemblies.ToArray();
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();

// TODO: We could add an option to do enable sha- validation

var contentBytes = await response.Content.ReadAsStreamAsync();

return contentBytes;
}

private string GetDllLocationFromOptions((string assemblyToLoad, BlazyAssemblyOptions options) assemblyToLoad)
private string GetDllLocationFromOptions(BlazyAssemblyOptions options)
{
var options = assemblyToLoad.options;

var dllLocation = options == null ? // If options is null,
$"{navigationManager.BaseUri}/_framework/" : // use default path
options.AbsolutePath ?? // If AbsolutePath isn't null, use that.
(options.RelativePath != null ? $"{navigationManager.BaseUri}{assemblyToLoad.options.RelativePath}" : // If RelativePath isn't null, use base path + RelativePath
(options.RelativePath != null ? $"{navigationManager.BaseUri}{options.RelativePath}" : // If RelativePath isn't null, use base path + RelativePath
$"{navigationManager.BaseUri}/_framework/"); // Else just use default path

return dllLocation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public BlazyServiceProviderFactory(BlazyOptions options)

public BlazyBuilder CreateBuilder(IServiceCollection services)
{
services.AddSingleton<BlazyAssemblyLoader>();
services.AddSingleton<IAssemblyLoader, BlazyAssemblyLoader>();
var container = new BlazyBuilder(services);
return container;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace RonSijm.Blazyload.Features.DIComponents;

public interface IAssemblyLoader
{
event Action<List<Assembly>> OnAssembliesLoaded;
Task<List<Assembly>> LoadAssemblyAsync(string assemblyToLoad);
Task<List<Assembly>> LoadAssembliesAsync(IEnumerable<string> assembliesToLoad);
}

0 comments on commit 23f8b42

Please sign in to comment.