是否可以用"弱"引用替换对具有强名称的程序集的引用?

Hei*_*nzi 17 .net strongname assemblies reference

我正在编写一个需要SQL Server SMO库的.NET工具.我不在乎它是Server 2005(9.0),2008(10.0)还是2008 R2(可能是10.5,没有检查)的版本.SMO库与SQL Server一起安装,因此我可以放心地假设在安装了SQL Server的任何系统上,也可以使用某些版本的SMO库.

不幸的是,SMO库名称很大:如果我在项目中添加对SMO 9.0的引用,FileNotFoundException如果客户系统上只有SMO 10.0 ,则会失败(),反之亦然.

有没有办法告诉编译器任何版本的库对我来说都没问题?或者我是否真的必须分发3个相同版本的工具,每个版本都编译为不同版本的SMO?


免责声明:我知道可以重新分发SMO库(以及SMO库所需的库).但是(a)一个超薄的100KB独立EXE和(b)安装了大量先决条件的完整安装包之间存在很大差异.

免责声明2:我知道以下重复:

但是,所提供的解决方案并不合适.在问题1中,开发人员可以控制引用的DLL(我没有); 在问题2中,开发人员可以控制目标系统(我也没有).

Tim*_*oyd 6

您可以使用程序集绑定重定向.

例如:

 <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Telerik.Web.UI" publicKeyToken="121fae78165ba" />
        <bindingRedirect
               oldVersion="2010.0.0.1"
               newVersion="2011.1.315.40" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
Run Code Online (Sandbox Code Playgroud)

更新

我从你的评论中看到,我们必须反过来考虑一下这一点.

这是一种非常有前途的方法,但不幸的是,它只是将对版本X的依赖性替换为对版本Y的(强)依赖性.我仍然依赖于某个特定版本.

我做了一些实验,我编译了一个版本的程序集:4.0.0.0,但想确保它会加载该版本,加上一些选定的旧版本.这样,您不依赖于任何单个版本,而是依赖于您配置的任何版本.

VersionedAssembly如果系统上有以下任何版本,则以下内容将确保将加载:4.0.0.0,3.0.0.0,2.0.0.0,1.0.0.0.

   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <dependentAssembly>
            <assemblyIdentity name="VersionedAssembly" publicKeyToken="20d85e" />
            <bindingRedirect oldVersion="4.0.0.0" newVersion="1.0.0.0"/>
         </dependentAssembly>
         <dependentAssembly>
            <assemblyIdentity name="VersionedAssembly" publicKeyToken="20d84e" />
            <bindingRedirect oldVersion="4.0.0.0" newVersion="2.0.0.0"/>
         </dependentAssembly>
         <dependentAssembly>
            <assemblyIdentity name="VersionedAssembly" publicKeyToken="20d84e" />
            <bindingRedirect oldVersion="4.0.0.0" newVersion="3.0.0.0"/>
         </dependentAssembly>
      </assemblyBinding>
   </runtime>
Run Code Online (Sandbox Code Playgroud)


Lad*_*nka 6

据我所知,不可能删除对精确版本的依赖.这是强名称存在的原因之一 - 避免版本不匹配.程序集的内部甚至公共接口可以在版本之间进行更改,您可以发现新版本与旧版本不向后兼容.因为.NET会查找编译期间使用的版本以确保应用程序正常工作.

如果第三方决定其新版本向后兼容,并且他们将程序集部署到GAC,则可以添加将自动重定向的发布者策略.

如果您决定强制加载另一个程序集,则可以使用@chibacity提到的方法或实现处理程序AppDomain.CurrentDomain.AssemblyResolve.当.NET无法找到引用的程序集时,会触发此事件,您可以实现自己的逻辑来查找并通过调用加载它Assembly.LoadFrom.在这种情况下,完全取决于您加载的版本.

  • 脚注:如果未签名的汇编"A"依赖于签名的"B"v1,通过对"B"的强名称引用,通过处理`AssemblyResolve`事件,您可以使`A`使用`B` v2但*仅当`B` v2也签名*.如果`B` v2没有签名,'A`将拒绝使用它. (2认同)