.Net5 版本容错的装配加载

.Net5 version-tolerant assembly loading

提问人:Ildrial 提问时间:4/27/2022 最后编辑:Ildrial 更新时间:5/2/2022 访问量:192

问:

我在 .Net5/C#,我正在努力解决。 我们有应用程序(我们称之为平台)U,它能够加载插件,例如插件P,引用Utilities U,它是平台的一部分并共享其版本。 我们的想法是,次要版本中的任何内容都应该兼容,即版本为 3.1.x.y 的 A 应该能够加载任何版本为 3.1.x.y 的 P。

现在,平台部署了版本 3.1.1.10,我们要加载的插件 P 是针对版本为 3.1.1.15 的应用程序 A 构建的。

这意味着,Platform现在与具有相同版本3.1.1.10的Utilities U一起运行。在打包我们的插件时,我们不包括平台中已经可用的任何内容,在本例中为 Utilities U。

加载插件时,我们调用:

Assembly.LoadFrom(pathToPluginDll);

毫不奇怪,在加载插件时,它还会尝试加载其依赖项 Utilities U 版本 3.1.1.15(我们在此不提供)。

我现在想要的只是加载平台已经提供的实用程序 3.1.1.10。我怎样才能做到这一点?

我做了一些研究,但找不到任何工作。对于 .NET Framework,BindingRedirect 似乎是解决此问题的简单方法,但对于 .NET5 了。 我还尝试了 EnableDynamicLoading / RollForward 和 deps.json 文件,但没有成功。

提前感谢您的任何提示/帮助。我觉得我错过了一些简单的东西。

C# .NET 加载 程序集解析

评论


答:

1赞 Ildrial 4/29/2022 #1

我能够找到 AssemblyResolve 的解决方案:

internal PluginLoader() {
    AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolver;
}

...

private static Assembly AssemblyResolver(object source, ResolveEventArgs e) {
    var expectedAssembly = new AssemblyName(e.Name);
    var assembly = AppDomain.CurrentDomain.GetAssemblies()
        .SingleOrDefault(a => a.GetName().Name.Equals(expectedAssembly.Name));
    return VersionMatches(assembly.GetName().Version, expectedAssembly.Version) ? assembly : null;
}

我希望在某个配置级别找到一个解决方案(如绑定重定向),但这看起来很容易。不过,如果存在更好的解决方案,请告诉我。