In a Blazor app, I want to load an external assembly and execute a method. For this, I have created a new ASP.Net Core webapplication using the Blazor template.
Then, in
This is caused by the blazor linker stripping out the dependency to netstandard
since it's not explicitly used in the main WebAssemblyHost project.
When dynamically loading a DLL that uses netstandard
, it will assume that it was already loaded and crash.
If you plan to load assemblies dynamically, I recommend using
<BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking>
to ensure non of the base dependencies is stripped out.
After doing some further investigation, I've concluded that my problem is that my external library is not properly linked to the mono.net dependencies. This is why, when you build a Blazor app, it is compiled a second time to /dist/_framework/_bin.
I've found three possible solutions to this problem:
This way, your app will automatically be converted to a mono-compatible assembly when built. A simple peek in to a Blazor .csproj shows the dependencies needed to achieve this. For it to work, I had to change the .csproj of my external assembly:
from a default netstandard library:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>
into a web app:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RunCommand>dotnet</RunCommand>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="0.7.0" PrivateAssets="all" />
</ItemGroup>
</Project>
These are the only dependencies needed. On build, the compatible assembly will be found in the /dist/_framework/_bin folder. It can then be loaded using the methods described in the question.
This works, but feels a bit hacky because the only reason we're turning the library into a web app is so that it can compile itself into a properly linked assembly.
Another solution is to unzip the Nuget Package from Microsoft.AspNetCore.Blazor.Build and grab the netstandard.dll. It's found in the tools\mono\bcl\Facades
folder. Now, when doing the following in the main Blazor app:
var netstandard = await client.GetByteArrayAsync("http://localhost:62633/_framework/netstandard.dll");
var externallib = await client.GetByteArrayAsync("http://localhost:62633/_framework/MyCustomLib.dll");
AppDomain.CurrentDomain.Load(netstandard);
var assembly = AppDomain.CurrentDomain.Load(externallib);
then the unmodified netstandard 2.0 library MyCustomLib
will be loaded without errors.
The Blazor Build tools, currently found here, they have a ResolveRuntimeDependenciesCommand
command for the CLI which seems to do exactly what a blazor web app is doing when it spits output to /_framework/_bin.
I'm still looking at how this could be used to convert a "non blazor-webapp" assembly into a mono-compatible one.
Feel free to comment or answer with additional information. I'm leaving this question open until a "cleaner" solution is found.