Загрузка внешней сборки .NET Standard 2.0 с помощью Blazor - PullRequest
0 голосов
/ 20 января 2019

В приложении Blazor я хочу загрузить внешнюю сборку и выполнить метод.Для этого я создал новое веб-приложение ASP.Net Core с использованием шаблона Blazor.

Затем на странице 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.Боже мой.Полный код в этой библиотеке:

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

Результат:

Successful result in chrome's console

Как видите, это прекрасно работает, когда MyCustomLib.dll создается как .NET Framework библиотека классов.Однако я хочу использовать библиотеку классов .NET Standard .

Когда я создаю MyCustomLib.dll в качестве библиотеки .NET Standard 2.0 и запускаю то же самое приложение для блейзора, я получаюследующая ошибка в консоли браузера:

Не удалось загрузить файл или сборку 'netstandard, версия = 2.0.0.0, Culture = нейтральный, PublicKeyToken = cc7b13ffcd2ddd51' или одну из его зависимостей.

Я ожидаю, что mono.wasm загрузит необходимые зависимости для поддержки сборок .NET Standard.

  • Загрузка сборки в AppDomain дает тот же результат.
var assembly = AppDomain.CurrentDomain.Load(bytes); 
  • Переход на netstandard 1.6 дает мне похожую ошибку, этавремя около System.Runtime (потому что mono.wasm ожидает Mono.Runtime Я предполагаю).

  • Может быть, есть способ выполнить LoadAssembly в сборках, на которые ссылается пакет netstandard2.0,но я не знаю, как.

Как загрузить .NET Standard 2.0 в среду браузера с помощью Blazor?

1 Ответ

0 голосов
/ 20 января 2019

Проведя дальнейшее исследование, я пришел к выводу, что моя проблема в том, что моя внешняя библиотека неправильно связана с зависимостями mono.net.Вот почему, когда вы создаете приложение Blazor, оно во второй раз компилируется в /dist/_framework/_bin.

Я нашел три возможных решения этой проблемы:

1.Превратите внешнюю библиотеку классов в веб-приложение Blazor

Таким образом, ваше приложение будет автоматически преобразовано в моносовместимую сборку при сборке.Простой взгляд на 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.Затем его можно загрузить, используя методы, описанные в вопросе.

Этот работает , но выглядит немного странно, потому что единственная причина, по которой мы превращаем библиотеку в веб-приложение, заключается в том, чтоон может скомпилировать себя в правильно связанную сборку.

2. Загрузить моно-фасад netstandard2.0

Другое решение - разархивировать пакет Nuget из Microsoft.AspNetCore.Blazor.Build. и возьмите 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 будет загружена без ошибок.

  • Нет необходимости менять его на веб-приложение
  • Это работает , но оно выглядит даже более хакерным, чем первое решение, не зная, произойдет ли это позже на этом пути ...

3. Используйте инструменты Blazor Build

Инструменты Blazor Build, в настоящее время найденные здесь , у них есть команда ResolveRuntimeDependenciesCommand для CLI, которая, кажется, делает именно то, чтовеб-приложение Blazor делает, когда оно выводит вывод в / _framework / _bin.Я все еще смотрю на то, как это можно использовать для преобразования сборки «non blazor-webapp» в моносовместимую.

Не стесняйтесь комментировать или отвечать с дополнительной информацией.Я оставляю этот вопрос открытым, пока не будет найдено «более чистое» решение.

...