类库的 app.config 中的绑定重定向有啥作用吗?

Posted

技术标签:

【中文标题】类库的 app.config 中的绑定重定向有啥作用吗?【英文标题】:Do binding redirects in app.config for class libraries do anything?类库的 app.config 中的绑定重定向有什么作用吗? 【发布时间】:2018-06-30 20:12:05 【问题描述】:

我经常使用的 VS 解决方案包括一个单个可执行项目(控制台应用程序、Web 应用程序)和许多类库项目,它们都被可执行文件引用。

在使用 NuGet 和安装包时,通常会为每个项目创建一个 app.config 文件,通常只包含一个绑定重定向列表,该列表整合了所引用程序集的版本。有时会有一些第三方库特定的内容(如 Entity Framework 配置部分),但我们暂时将其放在一边。

当我构建解决方案并使用主可执行项目的二进制文件时,我在构建输出中看到所有类库项目程序集以及相应的 *.config 文件(app.config 文件重命名为 AssemblyName.config建成时)。

在启动主可执行文件时,类库程序集的配置文件是否生效?还是只是在这种情况下有效的可执行文件的app.config 文件?如果在一些类库项目上设置了一些绑定重定向,而在主可执行项目上设置了一些不同的绑定重定向怎么办——这些是如何组合的,哪个优先?

我尝试在网上对此进行研究,从我所阅读的内容来看,在我看来,用于不可执行程序集的 app.config 文件是无用的(关于绑定重定向)。有人可以证实这一点或详细说明这个话题吗?

如果是这样,如果这些app.config 文件仅包含绑定重定向,那么在类库中包含由 NuGet 创建的这些 app.config 文件是否真的不可取?在我看来,NuGet 不应该为类库项目创建那些绑定重定向,因为它只会增加对实际应用哪些设置的混淆。


我发现了这些关于该主题的现有 Stack Overflow 问题,但他们接受的答案实际上是矛盾的,即使它们被标记为彼此重复

Why NuGet adds app.config with assemblyBinding to LIBRARY projects during a NuGet package update?

Is the bindingRedirect .config file needed or all assemblies in an application?

The accepted answer to the first question 提到 app.config 文件实际上是在编译时使用的,这意味着它们可能会生效。像MSDN 和MSBuild source code 这样的源被引用作为它在编译时使用的证明。不幸的是,我对 MSBuild 不够精通,无法理解它是如何使用的,以及它是否真的是一个有效的论点。

谁能描述一个示例场景来证明带有类库绑定重定向的 app.config 可以做任何事情?

【问题讨论】:

查看这个答案:***.com/questions/43365736/… @noob 说的是主要可执行项目的 app.config。解决方案中所有类库的配置都不会产生这种效果。 【参考方案1】:

我有多个具有类似设置的应用程序 - Web 应用程序引用多个库项目,每个库项目都有自己的 nuget 包等,根据我的个人经验,在运行时不考虑库项目中的程序集绑定。

在根应用程序 (web/console) 中指定的 web 或应用程序配置的绑定是唯一重要的。我所有的库项目都设置为 app.config 文件的“复制到输出目录”设置为“不复制” - 这样我的输出文件夹就不会被 dll 及其配置文件弄乱。

Here is the link 表示程序集是如何加载的,它在哪里被搜索以及它的顺序。他们在文章中没有任何地方谈论单个项目配置文件。

希望对您有所帮助。

【讨论】:

据我所知,app.config 文件默认设置为“不复制”,它们仍然会到达构建输出。请注意,它们将不再称为“app.config”,而是“YourAssemblyName.dll.config”,这是标准行为。另外,您能否解决我在问题中引用的在编译时使用 app.config 的说法?我在问题中引用了 MSDN 或 MSBuild 源代码等来源,这表明在编译时存在一些行为。【参考方案2】:

根据this old msdn article:

应用程序配置文件是用于控制程序集绑定的 XML 文件。它可以将应用程序从使用并行程序集的一个版本重定向到同一程序集的另一个版本。这称为按应用程序配置。应用程序配置文件仅适用于特定的应用程序清单和依赖程序集。使用嵌入式 [ISOLATIONAWARE_MANIFEST_RESOURCE_ID] 清单编译的独立组件需要单独的应用程序配置文件。使用 CreateActCtx 管理的清单需要单独的应用程序配置文件。

所以只有 ISOLATIONAWARE_MANIFEST_RESOURCE_ID 设置的 dll 实际上使用独立的应用程序配置,否则它会延迟到主进程配置文件。

有关什么是 ISOLATIONAWARE 的更多信息,您可以阅读更深入的 other MSDN article。

ISOLATIONAWARE_MANIFEST_RESOURCE_ID 主要用于 DLL。它 如果 dll 需要私有依赖项而不是 进程默认。例如,如果一个 dll 依赖于 comctl32.dll 版本 6.0.0.0。它应该有一个 RT_MANIFEST 类型的资源,ID ISOLATIONAWARE_MANIFEST_RESOURCE_ID 取决于 comctl32.dll 版本 6.0.0.0,这样即使进程可执行文件需要 comctl32.dll 版本 5.1,dll 本身仍然会使用正确的版本 comctl32.dll。

【讨论】:

我在问题(行下方)中提到的编译时使用 app.configs 怎么样? 在第一个引号中它指定在编译时仅使用主 app.configs 重定向除非依赖库是使用 [ISOLATIONAWARE_MANIFEST_RESOURCE_ID编译的>] 标志。 如果您转到 [MSBUILD 源][1],它只会从一个应用配置 [1] 加载重定向:github.com/Microsoft/msbuild/blob/… 感谢您对此进行调查。 ISOLATIONAWARE_MANIFEST_RESOURCE_ID 不只与运行时有关吗?这些标志中的任何一个在编译时如何使用?关于MSBuild,难道不是说如果我在构建类库项目,它使用的是一个app.config文件——类库项目的app.config文件吗?【参考方案3】:

答案是也许。根据项目的类型,库文件是。一些库项目在尊重库配置文件的环境中运行(例如 Azure Web 角色),但这不是常态。

查看我的回答here了解更多详情。

【讨论】:

【参考方案4】:

一般只有一个配置文件,就是可执行文件的配置文件(.exe.config, web.config)。

任何程序集重定向都必须放在可执行文件的配置文件中。

dll的配置文件需要使用ConfigurationManager类手动加载。另请参阅此问题Equivalent to 'app.config' for a library (DLL)

【讨论】:

我同意你的观点,我也这么认为。但是您能否为该声明提供一些来源?另外,请阅读相关问题行下方的问题部分。那里有一些相互矛盾的说法,他们引用 MSDN 和 MSBuild source code 等来源说 app.configs 实际上是在编译时使用的(我不相信)。 @我唯一能想到的可能需要的是在单元测试期间。单元测试运行器将主要加载被测 dll 和 dll 的配置文件(如果存在)。我认为跑步者也会应用重定向 我同意,我一直将单元测试项目视为可执行项目,因为它们有自己的入口点,而且通常还有所有 DI 设置,它们只是感觉更像可执行文件给我。对我来说,类库与单元测试项目完全不同。【参考方案5】:

不,只有可执行文件的app.config 才会生效。例如,如果您有一个托管 WCF 服务的控制台应用程序,并且在您的 WCF 服务中使用了 ConfigurationManager.AppSettings,则 AppSettings 将来自控制台主机 app.config 文件。如果你启动另一个控制台应用程序(ConsoleClient)来尝试连接到 ConsoleHost,那么在 ConsoleClient 可以说是“正在执行”的部分(例如在它的 main 方法中),它将使用 ConsoleClient 的app.config,但是一旦开始使用 WCF 服务,WCF 服务就会委托使用 ConsoleHost 的app.config。 (请注意,最后一点与 WCF 背后的细节更相关。)

令人惊讶的是,msdn 提供了这么好的资源: https://social.msdn.microsoft.com/Forums/vstudio/en-US/e13194df-6308-4cbe-973c-f6a462f43eae/how-can-wcf-library-dll-access-application-settings?referrer=http://social.msdn.microsoft.com/Forums/vstudio/en-US/e13194df-6308-4cbe-973c-f6a462f43eae/how-can-wcf-library-dll-access-application-settings?referrer=http://social.msdn.microsoft.com/Forums/vstudio/en-US/e13194df-6308-4cbe-973c-f6a462f43eae/how-can-wcf-library-dll-access-application-settings?forum=wcf

【讨论】:

您能否提供该声明的来源?另外,请阅读相关问题行下方的问题部分。那里有一些相互矛盾的说法,他们引用 MSDN 和 MSBuild source code 等来源说 app.configs 实际上是在编译时使用的(我不相信)。

以上是关于类库的 app.config 中的绑定重定向有啥作用吗?的主要内容,如果未能解决你的问题,请参考以下文章

类库的 app.config

在类库的 App.config 中使用 ConfigurationManager.GetSection

程序集绑定重定向不起作用

Visual Studio/MSBuild 将引用的类库的 app.config 作为 *.dll.config 复制到当前项目的 bin 文件夹

Thymeleaf 中的视图和重定向有啥区别?

包括来自类库的服务引用