使用 blazor 加载外部 .NET Standard 2.0 程序集

编程入门 行业动态 更新时间:2024-10-19 10:20:00
本文介绍了使用 blazor 加载外部 .NET Standard 2.0 程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

在 Blazor 应用程序中,我想加载一个外部程序集并执行一个方法.为此,我使用 Blazor 模板创建了一个新的 ASP.Net Core 网络应用程序.

然后,在一个 Razor 页面(将由浏览器/wasm 编译和执行)中,我使用反射来加载程序集并运行该方法(基于代码

如您所见,当 MyCustomLib.dll 构建为 .NET Framework 类库时,这非常有效.但是,我想使用 .NET Standard 类库.

当我将 MyCustomLib.dll 构建为 .NET Standard 2.0 库并执行相同的 blazor 应用程序时,我在浏览器的控制台中收到以下错误:

无法加载文件或程序集netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51"或其依赖项之一.

我希望 mono.wasm 会加载必要的依赖项来支持 .NET Standard 程序集.

  • 将程序集加载到 AppDomain 中会产生相同的结果.

var assembly = AppDomain.CurrentDomain.Load(bytes);

  • 切换到 netstandard 1.6 给了我一个类似的错误,这次是关于 System.Runtime(因为 mono.wasm 期望 Mono.Runtime 我假设).

  • 也许有一种方法可以对 netstandard2.0 包引用的程序集执行 LoadAssembly,但我不知道如何.

如何使用 Blazor 将 .NET Standard 2.0 加载到浏览器环境中?

解决方案

经过进一步调查后,我得出结论,我的问题是我的外部库没有正确链接到 mono 依赖项.这就是为什么当您构建 Blazor 应用程序时,它会第二次编译到/dist/_framework/_bin.

我找到了三种可能的解决方案:

1. 将外部类库变成 Blazor Web 应用

这样,您的应用程序在构建时将自动转换为单一兼容程序集.对 Blazor .csproj 的简单窥视显示了实现此目的所需的依赖项.为了让它工作,我不得不改变我的外部程序集的 .csproj:

来自默认的网络标准库:

<属性组><TargetFramework>netstandard2.0</TargetFramework></PropertyGroup></项目>

进入网络应用程序:

<属性组><TargetFramework>netstandard2.0</TargetFramework><RunCommand>dotnet</RunCommand><LangVersion>7.3</LangVersion></PropertyGroup><项目组><PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="0.7.0" PrivateAssets="all"/></项目组></项目>

这些是唯一需要的依赖项.在构建时,将在/dist/_framework/_bin 文件夹中找到兼容的程序集.然后可以使用问题中描述的方法加载它.

这有效,但感觉有点麻烦,因为我们将库转变为 Web 应用程序的唯一原因是它可以将自身编译为正确链接的程序集.

2.加载netstandard2.0 mono门面

另一种解决方案是从 Microsoft.AspNetCore.Blazor 解压缩 Nuget 包.Build 并获取 netstandard.dll.它位于 toolsmonoclFacades 文件夹中.现在,在 Blazor 主应用程序中执行以下操作时:

var netstandard = await client.GetByteArrayAsync("localhost:62633/_framework/netstandard.dll");var externallib = await client.GetByteArrayAsync("localhost:62633/_framework/MyCustomLib.dll");AppDomain.CurrentDomain.Load(netstandard);var assembly = AppDomain.CurrentDomain.Load(externallib);

然后 未修改 netstandard 2.0 库 MyCustomLib 将被正确加载.

  • 无需将其更改为网络应用
  • 这个有效,但感觉比第一个解决方案更hacker,不确定这是否会在以后的过程中失败......
3. 使用 Blazor 构建工具

Blazor 构建工具,目前可在此处找到,他们有一个用于 CLI 的 ResolveRuntimeDependenciesCommand 命令,这似乎与 blazor Web 应用程序在将输出输出到/_framework/_bin 时所做的完全一样.我仍在研究如何将其用于将非 blazor-webapp"程序集转换为与单声道兼容的程序集.

请随时发表评论或回答附加信息.我将这个问题悬而未决,直到找到更清洁"的解决方案.

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 a Razor Page (which will be compiled and executed by browser/wasm) I use reflection to load the assembly and run the method (based on code found here)

// download external assembly from server HttpClient client = new HttpClient(); var bytes = await client.GetByteArrayAsync("localhost:62633/_framework/MyCustomLib.dll"); //load assembly var assembly = System.Reflection.Assembly.Load(bytes); // get type/method info var type = assembly.GetType("MyCustomLib.MyCustomClass"); var method = type.GetMethod("WriteSomething"); // instantiate object and run method object classInstance = Activator.CreateInstance(type, null); method.Invoke(classInstance, null);

The method WriteSomething contains a single Console.WriteLine() which prints something in the browser's console, thanks to blazor/mono.wasm goodness. The complete code in this library is:

namespace MyCustomLib { public class MyCustomClass { public void WriteSomething() { System.Console.WriteLine("This is printed from a loaded dll 3 !"); } } }

Result:

As you can see, this works great when MyCustomLib.dll is built as a .NET Framework Class Library. However, I want to use a .NET Standard Class Library.

When I build a MyCustomLib.dll as a .NET Standard 2.0 library, and execute the same blazor app, I get the following error in the browser's console:

Could not load file or assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies.

I would expect mono.wasm would have loaded the necessary dependencies to support .NET Standard assemblies.

  • Loading the assembly into the AppDomain yields the same result.

var assembly = AppDomain.CurrentDomain.Load(bytes);

  • Switching down to netstandard 1.6 gives me a similar error, this time about System.Runtime (because mono.wasm expects Mono.Runtime I assume).

  • Maybe there's a way to perform LoadAssembly on the assemblies referenced by the netstandard2.0 package, but I wouldn't know how.

How can I load a .NET Standard 2.0 into the browser environment using Blazor?

解决方案

After doing some further investigation, I've concluded that my problem is that my external library is not properly linked to the mono 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:

1. Turn the external class library into a Blazor Web app

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.

2. Load the netstandard2.0 mono facade

Another solution is to unzip the Nuget Package from Microsoft.AspNetCore.Blazor.Build and grab the netstandard.dll. It's found in the toolsmonoclFacades folder. Now, when doing the following in the main Blazor app:

var netstandard = await client.GetByteArrayAsync("localhost:62633/_framework/netstandard.dll"); var externallib = await client.GetByteArrayAsync("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.

  • No need to change it to a web app
  • This works, but it feels even hackier than the first solution, unsure whether this will fail later along the way...
3. Use the Blazor Build tools

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.

更多推荐

使用 blazor 加载外部 .NET Standard 2.0 程序集

本文发布于:2023-11-13 14:44:37,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1584613.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:加载   程序   blazor   NET   Standard

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!