簡體   English   中英

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

[英]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 !");
        }
    }
}

結果:

chrome 控制台中的成功結果

如您所見,當 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 程序集。

  • 將程序集加載到 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.net 依賴項。 這就是為什么在構建 Blazor 應用程序時,它會第二次編譯到 /dist/_framework/_bin。

我找到了解決這個問題的三種可能的方法:

1. 將外部類庫變成 Blazor Web 應用

這樣,您的應用程序在構建時將自動轉換為單一兼容程序集。 對 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 應用程序的唯一原因是它可以將自身編譯為正確鏈接的程序集。

2.加載netstandard2.0 mono門面

另一種解決方案是從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將被正確加載。

  • 無需將其更改為 Web 應用程序
  • 有效,但感覺比第一個解決方案更hacker,不確定這是否會在此過程中失敗......

3. 使用 Blazor 構建工具

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM