如何通过 Unity Container 5 的配置文件(运行时配置)使用外部插件

问题描述 投票:0回答:1

我正在尝试设置一个使用 Unity Container 5 的简单 .NET Core 3.1 项目(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

{"类型名称或别名 Implements.ImplementationN, 实施无法解决。请检查您的配置 文件并验证此类型名称。"}

我已将代码上传到 GitHub

附注Visual Studio 2019 16.4.4 企业版、Windows 10 1909 x64 专业版

P.P.S。为 .NET Framework 4.8 编译的相同代码工作正常 - GitHub

更新

为了澄清更多 - 我需要一种没有任何项目引用 Implements.dll 的方法,我应该能够更改特定的实现(通过更改 config.json)而无需重新编译。

c# .net dependency-injection unity-container .net-core-3.1
1个回答
0
投票

我发现这更像是一个“.NET Core 程序集加载”问题,而不是 IoC 容器问题。

长话短说,如果您的应用程序没有专门引用该程序集,您需要告诉 .NET Core 程序集加载器从哪里获取它即使它位于您的 BIN 文件夹中

因此,如果您(像我一样)不想拥有一个引用您需要的all实现库的引导库,但您想通过配置文件进行运行时配置 - 您应该执行以下操作。

来自 Autofac IoC 示例存储库:

// 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>();

工作起来很有魅力。

P.S. 来自 Microsoft

的更多信息
© www.soinside.com 2019 - 2024. All rights reserved.