当前位置: 首页 > news >正文

.NET 应用启用与禁用自动生成绑定重定向 (bindingRedirect),解决不同版本 dll 的依赖问题

当你的项目中多个不同的项目以及不同的依赖存在不同的依赖程序集时,可能会因为依赖于不同版本的程序集而产生冲突。而绑定重定向可以帮助解决不同程序集的依赖版本不同的问题,使整个程序使用统一个版本的 dll 来运行整个应用程序。

然而,如果我们就是需要使用一个分离的不同版本,那么我们就需要禁用掉自动生成绑定重定向。本文介绍如何禁用自动生成绑定重定向。


本文的结论只有一句,就是在项目中设置属性 <AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>。阅读本文全文是了解更多与绑定重定向此场景相关的知识。

本文内容

    • 绑定重定向
    • 引用同名但不同版本的 dll
    • 禁用绑定重定向

绑定重定向

从 .NET Framework 4.5.1 开始到后面的 .NET Core 所有版本,编译器会自动向你的程序集中插入绑定重定向。如果你升级使用了新的 csproj 格式,即便你用了旧的 .NET Framework 也会自动生成绑定重定向。

关于新旧 csproj 格式,你可以参考我的另一篇博客:将 WPF、UWP 以及其他各种类型的旧 csproj 迁移成基于 Microsoft.NET.Sdk 的新 csproj - walterlv。

你可以在你的应用程序的 App.config 文件中查看到自动生成的绑定重定向。当然,编译之后这个 App.config 文件会编程 “你的程序集名称.config” 文件,例如对于我的 Walterlv.Demo.exe 程序对应 Walterlv.Demo.exe.config 文件。

一个典型的包含绑定重定向的文件大概是下面这样的:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
    </startup>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
                <bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
            </dependentAssembly>
            <dependentAssembly>
                <assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
                <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

上面 dependentAssembly 以及 bindingRedirect 就是在描述绑定重定向。

对于上面的代码,指的是:

  1. 如果依赖中发现了任何 0.0.0.0-11.0.0.0 区间版本号的 Newtonsoft.Json 程序集的引用,都将使用 11.0.0.0 版本的。
  2. 如果以来中发现了任何 0.0.0.0-4.0.3.0 区间版本号的 System.ValueTuple 程序集的引用,都将使用 4.0.3.0 版本的(这个其实使用的 NuGet 包版本是 4.5)。

引用同名但不同版本的 dll

绑定重定向多数时候都是在帮助我们解决依赖问题,然而我们总有一些时候不是按照常规的方式来使用依赖,例如下文这样的方式:

  • 引用不用版本dll - dang13579的专栏 - CSDN博客
  • C# 引用不同版本dll - 晒太阳的猫
  • 同一个解决方案或有依赖关系的两个项目引用同名但不同版本的DLL - gudi - 博客园

以上文章的场景,是需要在同一个解决方案的不同项目中引用不同版本的同名 dll。解决方法是像下面这样:

<dependentAssembly>
    <assemblyIdentity name="LiteDB" publicKeyToken="4ee40123013c9f27" culture="neutral" />
    <codeBase version="2.0.2.0" href="LiteDB.2.0.2.0\LiteDB.dll" />
    <codeBase version="4.0.0.0" href="LiteDB.4.0.0.0\LiteDB.dll" />
</dependentAssembly>

于是,如果引用了 2.0.2.0 版本的 LiteDB 的时候,会去应用程序所在目录的 LiteDB.2.0.2.0 子目录中查找名为 LiteDB.dll 的引用 dll;而如果引用了 4.0.0.0 版本的 LiteDB 的时候,会去应用程序所在目录的 LiteDB.4.0.0.0 子目录中查找名为 LiteDB.dll 的引用 dll。这种方式使用两个 dll 互不干扰。

禁用绑定重定向

如果你的项目从 .NET Framework 4.5 或者更早版本升级到 .NET Framework 4.5.1 或者 .NET Core 的版本,或者 csproj 的格式升级到了新的基于 Microsoft.NET.Sdk 的版本,那么绑定重定向就会从之前的手动编程自动生成。

但是如果你编写了上一节中我们讲到的你需要引用同名程序集的多个版本的时候,如果依然自动生成绑定重定向,那么上面的功能会失效。

解决方法,便是禁用自动生成绑定重定向。在你的主项目中添加一个属性:

<AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>

参考资料

  • Enable or disable autogenerated binding redirects - Microsoft Docs

我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

相关文章:

  • 为什么 C# 的 string.Empty 是一个静态只读字段,而不是一个常量呢?
  • 透明度叠加算法:如何计算半透明像素叠加到另一个像素上的实际可见像素值(附 WPF 和 HLSL 的实现)
  • C#/.NET 调试的时候显示自定义的调试信息(DebuggerDisplay 和 DebuggerTypeProxy)
  • 详解 .NET 反射中的 BindingFlags 以及常用的 BindingFlags 使用方式
  • 在 csproj 文件中使用系统环境变量的值(示例将 dll 生成到 AppData 目录下)
  • git subtree 的使用
  • 让你的 VSCode 具备调试 C# 语言 .NET Core 程序的能力
  • 手工编辑 tasks.json 和 launch.json,让你的 VSCode 具备调试 .NET Core 程序的能力
  • C#/.NET 如何结束掉一个进程
  • C#/.NET 移动或重命名一个文件夹(如果存在,则合并而不是出现异常报错)
  • 如何创建应用程序清单文件 App.Manifest,如何创建不带清单的应用程序
  • 应用程序清单 Manifest 中各种 UAC 权限级别的含义和效果
  • 启用 Windows 审核模式(Audit Mode),以 Administrator 账户来设置电脑的开箱体验
  • Windows 中的 UAC 用户账户控制
  • Windows 下使用 runas 命令以指定的权限启动一个进程(非管理员、管理员)
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • JS字符串转数字方法总结
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • SQLServer之索引简介
  • 好的网址,关于.net 4.0 ,vs 2010
  • 看域名解析域名安全对SEO的影响
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 面试遇到的一些题
  • 如何胜任知名企业的商业数据分析师?
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 使用API自动生成工具优化前端工作流
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 鱼骨图 - 如何绘制?
  • 再次简单明了总结flex布局,一看就懂...
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #pragma预处理命令
  • #Z0458. 树的中心2
  • (20050108)又读《平凡的世界》
  • (26)4.7 字符函数和字符串函数
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (二)PySpark3:SparkSQL编程
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (十)T检验-第一部分
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • (转)3D模板阴影原理
  • (轉)JSON.stringify 语法实例讲解
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • .dwp和.webpart的区别
  • .NET MVC、 WebAPI、 WebService【ws】、NVVM、WCF、Remoting
  • .net 发送邮件
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .NET下ASPX编程的几个小问题
  • .NET项目中存在多个web.config文件时的加载顺序
  • .NET序列化 serializable,反序列化