Как использовать внешние плагины через конфигурационный файл (конфигурация времени выполнения) с Unity Container 5 - PullRequest
0 голосов
/ 18 февраля 2020

Я пытаюсь настроить простой . NET Core 3.1 проект, который использует Unity Container 5 (https://github.com/unitycontainer/unity) .

Я добавил ссылку на последний пакет Unity Configuration 5.11.1 (https://www.nuget.org/packages/Unity.Configuration/).

Затем я создал интерфейс, реализацию и тестовое приложение с самым простым файлом конфигурации:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration" />
  </configSections>
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <container>
      <register
        type="Interfaces.InterfaceN, Interfaces"
        mapTo="Implementations.ImplementationN, Implementations">
      </register>
    </container>
  </unity>
</configuration>

Но я получаю System.InvalidOperationException :

{"Имя типа или псевдоним Реализации. РеализацияN, Реализации не могут быть разрешены. Пожалуйста, проверьте файл конфигурации и проверьте имя этого типа. "}

Я загрузил свой код в GitHub . Любая помощь приветствуется.

PS Visual Studio 2019 16.4.4 Enterprise, Windows 10 1909 x64 Professional

PPS Тот же код, скомпилированный для . NET Framework 4.8 отлично работает - GitHub

ОБНОВЛЕНИЕ: Чтобы уточнить больше - мне нужен подход без ЛЮБОЙ ссылки на проект Implementations.dll , я должен иметь возможность изменить конкретную c реализацию (через изменение конфигурации. json) без перекомпиляции.

1 Ответ

0 голосов
/ 19 февраля 2020

Я обнаружил, что это скорее проблема ". NET Загрузка сборки ядра", чем проблема контейнера Io C.

Короче говоря, если сборка не предназначена специально на который ссылается ваше приложение, вам нужно указать. NET Загрузчик сборки ядра, где его взять ДАЖЕ, ЕСЛИ ЭТО В ВАШЕМ ПАКЕТЕ БИН .

Так что если вы (как и я) не вы хотите иметь библиотеку bootstrap, которая ссылается на все библиотеки реализации, которые вам нужны, но вы хотите иметь конфигурацию во время выполнения через файл конфигурации - вы должны сделать следующее.

из Autofa c Io C репозиторий примеров:

// THIS IS THE MAGIC!
// .NET Core assembly loading is confusing. Things that happen to be in your bin folder don't just suddenly
// qualify with the assembly loader. If the assembly isn't specifically referenced by your app, you need to
// tell .NET Core where to get it EVEN IF IT'S IN YOUR BIN FOLDER.
// https://stackoverflow.com/questions/43918837/net-core-1-1-type-gettype-from-external-assembly-returns-null
//
// The documentation says that any .dll in the application base folder should work, but that doesn't seem
// to be entirely true. You always have to set up additional handlers if you AREN'T referencing the plugin assembly.
// https://github.com/dotnet/core-setup/blob/master/Documentation/design-docs/corehost.md
//
// To verify, try commenting this out and you'll see that the config system can't load the external plugin type.
var executionFolder = Path.GetDirectoryName(typeof(Program).Assembly.Location);
AssemblyLoadContext.Default.Resolving += (AssemblyLoadContext context, AssemblyName assembly) =>
{
     // DISCLAIMER: NO PROMISES THIS IS SECURE. You may or may not want this strategy. It's up to
     // you to determine if allowing any assembly in the directory to be loaded is acceptable. This
     // is for demo purposes only.
     return context.LoadFromAssemblyPath(Path.Combine(executionFolder, $"{assembly.Name}.dll"));
 };

И после этого следующий код

var container = new UnityContainer().LoadConfiguration();

var type = container.Resolve<InterfaceN>();

работает как шарм.

PS Дополнительная информация от Microsoft

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...