[英]Loading an external .NET Standard 2.0 assembly with blazor
在 Blazor 應用程序中,我想加載一個外部程序集並執行一個方法。 為此,我使用 Blazor 模板創建了一個新的 ASP.Net Core Web 應用程序。
然后,在 Razor 頁面(將由瀏覽器/wasm 編譯和執行)中,我使用反射加載程序集並運行該方法(基於此處找到的代碼)
// download external assembly from server
HttpClient client = new HttpClient();
var bytes = await client.GetByteArrayAsync("http://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);
方法WriteSomething
包含一個Console.WriteLine()
,它在瀏覽器的控制台中打印一些東西,這要歸功於 blazor/mono.wasm 的優點。 這個庫中的完整代碼是:
namespace MyCustomLib
{
public class MyCustomClass
{
public void WriteSomething()
{
System.Console.WriteLine("This is printed from a loaded dll 3 !");
}
}
}
結果:
如您所見,當 MyCustomLib.dll 構建為.NET Framework類庫時,這非常有效。 但是,我想使用.NET 標准類庫。
當我將MyCustomLib.dll
構建為 .NET Standard 2.0 庫並執行相同的 blazor 應用程序時,我在瀏覽器的控制台中收到以下錯誤:
無法加載文件或程序集“netstandard,Version=2.0.0.0,Culture=neutral,PublicKeyToken=cc7b13ffcd2ddd51”或其依賴項之一。
我希望 mono.wasm 會加載必要的依賴項來支持 .NET Standard 程序集。
var assembly = AppDomain.CurrentDomain.Load(bytes);
切換到 netstandard 1.6 給了我一個類似的錯誤,這次是關於System.Runtime
(因為 mono.wasm 期望Mono.Runtime
我假設)。
也許有一種方法可以對 netstandard2.0 包引用的程序集執行LoadAssembly
,但我不知道如何。
如何使用 Blazor 將 .NET Standard 2.0 加載到瀏覽器環境中?
在做了一些進一步的調查之后,我得出結論,我的問題是我的外部庫沒有正確鏈接到 mono.net 依賴項。 這就是為什么在構建 Blazor 應用程序時,它會第二次編譯到 /dist/_framework/_bin。
我找到了解決這個問題的三種可能的方法:
這樣,您的應用程序在構建時將自動轉換為單一兼容程序集。 對 Blazor .csproj 的簡單窺視顯示了實現此目的所需的依賴項。 為了讓它工作,我不得不改變我的外部程序集的 .csproj:
來自默認的網絡標准庫:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>
進入網絡應用程序:
<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>
這些是唯一需要的依賴項。 在構建時,將在 /dist/_framework/_bin 文件夾中找到兼容的程序集。 然后可以使用問題中描述的方法加載它。
這有效,但感覺有點麻煩,因為我們將庫轉換為 Web 應用程序的唯一原因是它可以將自身編譯為正確鏈接的程序集。
另一種解決方案是從Microsoft.AspNetCore.Blazor.Build解壓縮 Nuget 包並獲取 netstandard.dll。 它位於tools\\mono\\bcl\\Facades
文件夾中。 現在,在 Blazor 主應用程序中執行以下操作時:
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);
那么未修改的netstandard 2.0 庫MyCustomLib
將被正確加載。
Blazor 構建工具,目前可以在這里找到,它們有一個用於 CLI 的ResolveRuntimeDependenciesCommand
命令,這似乎與 blazor Web 應用程序在將輸出輸出到 /_framework/_bin 時所做的完全一樣。 我仍在研究如何將其用於將“非 blazor-webapp”程序集轉換為與單聲道兼容的程序集。
隨意評論或回答其他信息。 在找到“更清潔”的解決方案之前,我將這個問題懸而未決。
這是由於 blazor 鏈接器剝離了對netstandard
的依賴,因為它沒有在主 WebAssemblyHost 項目中明確使用。
當動態加載使用netstandard
的 DLL 時,它會假設它已經加載並崩潰。
如果您打算動態加載程序集,我建議使用
<BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking>
以確保沒有刪除基本依賴項。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.