一段时间以来,我一直在研究一种安全和本地方法,该方法允许应用程序使用同一程序集的两个不同版本。有很多关于此问题的SO和在线文章,但是我阅读的每个解决方案都有一个“陷阱”。
让我们假设我们有两个使用不同版本的Newtonsoft
的第三方库(我们无法控制)(以Newtonsoft
为例,它可以是任何其他依赖项)。我们希望每个第三方库都使用针对它们构建的Newtonsoft
版本。以下是我遇到的一些解决方案(来自here和here):
使用单个版本
如果每个第三方库只能针对特定版本的依赖项运行,则不是很理想,有时甚至是不可能的。
使用GAC
真的不想。
使用AssemblyResolve
将解决主要问题,但是considered unsafe自己手动加载同一程序集的两个版本(而不是让运行时处理此类任务)。
使用<codebase>
这是最有前途的解决方案。我了解的方式是让运行时处理加载同一程序集的不同版本,我的假设是,这样做会比使用AssemblyResolve
手动方式安全。我只是认为这是LAC (Local Assembly Cache)™
。 但是,据我了解,将其放在类库的App.config
(而不是可执行文件)中将被完全忽略。这是我的情况:
我的应用是用C++
开发的,并且通过.NET
使用了C++/CLI
程序集。消耗的.NET
程序集是依赖于第三方库的程序集,后者本身依赖于同一程序集的不同版本(即Newtonsoft
)。因此,实际上我的问题是,使用<codebase>
开发主应用程序/可执行文件时,有没有办法使用C++
?有没有办法让<codebase>
类库使用.NET
?
如果在主应用程序是<codebase>
的情况下C++
无法工作,我唯一的选择是安装最新版本的依赖项(即Newtonsoft
),并祈祷它是向后兼容,以便依赖较旧版本的第3方库仍可以在运行时使用最新版本?
编辑
我遵循汉斯的建议,将<codeBase>
放在与可执行文件同名的配置文件中,效果很好。例如,配置结构可以如下:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="DependencyName" culture="neutral" publicKeyToken="DependencyPublishToken" />
<codeBase version="1.0.0.0" href="DependencyName1.0.0.0/DependencyName.dll"/>
<codeBase version="2.0.0.0" href="DependencyName2.0.0.0/DependencyName.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
我想确认的唯一想法(在任何地方都找不到答案)是否像将程序集放入GAC一样安全?例如,这样做还是会导致here提到的问题,还是安全的,因为我们让运行时处理所有事情,并确保仅对强命名程序集执行上述操作?