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

Assembly binding redirects are as valid in a class library as they are in executable projects.

Think about this; when building your application, how will the compiler know which version of referenced assemblies to use (for the class libraries)?

Often this will work just fine, without the redirects, but when you stumble over a machine that has a GAC'ed version of the assembly, you could get into trouble.

I suggest you read the assembly binding redirect documentation to better understand what it is and does.

NuGet adds the app.config with redirects to help you, and quite frankly, I don't get the fuzz about an extra app.config for everything to work as expected.

As of today, it will add redirects to all projects, except the following types:

  • WiX
  • JS
  • Nemerle
  • C++
  • Synergex
  • Visual Studio
  • Windows Store App

As far as I know, there's no way of turning this off. You could create an issue at Github if this is a problem.

The source code for adding assembly binding redirects can be found here.


The reason that the NuGet package manager adds assembly binding redirects to library projects is because there are types of projects where the output type is a library, but there are special mechanisms in place to assure that the library's app or web config file will be applied at runtime. This is opposed to more typical library usage that you're probably familiar with, wherein the library's config file is not used at all.

For example, Azure Web and Worker role projects in Azure SDK 1.8+ will produce libraries, but when they are wrapped in an exe by IIS, the library's config file will be set as the default for that exe. That way you get all your application configuration without having to explicitly publish a special config file with the same name as the wrapping executable, which is how it used to be done. Now the build process outputs the renamed config file (e.g. app.config -> myWebRoleLibrary.dll.config), and everything works as it should.

XUnit also does something similar; loading the app.config of the test assembly instead of the app config of the test runner process.

It's worth mentioning that you can also manually load a config file in any project, library or not. You would have to ensure that the config file ended up in the right place, but it is possible. This is less applicable for binding redirects though, since usually those are solely used by the assembly loader in the CLR. I suppose you could hook AssemblyLoad but now we're well on our way to poorly reinventing the wheel.

So, the answer to "is it necessary in my library project?" is maybe. If your library project is not a web or worker role or test project, and it doesn't manually load a configuration file, then the app.config is probably benign but unnecessary.

As for disabling it, you can only do that at the Visual Studio level. You can find the option in VS2019 at: Tools -> Options... -> NuGet Package Manager -> General -> Skip applying binding redirects.

What uses my configuration files?

The Compiler (csc.exe)

The compiler uses the config file of the assembly being built for one reason: to find and use supportPortability elements.

The link above lays out rare scenario where you would need that compiler option, but an overwhelming majority of users will not. Suffice it to say, if you don't know if you're using that feature, you are not.

It does not parse any of the other elements of the config file, including assembly binding redirects which are the elements that NuGet adds.

The Build Engine (msbuild)

MSBuild uses app configs in a few of its steps but importantly not to find the primary dependencies, which it will pass to csc.exe in the form of /reference: options.

In order to find the primary references MSBuild (and specifically the ResolveAssemblyReference task) will search a collection of paths enumerated in the common targets file. If it cannot find an explicit dependency in your csproj, it will issue a warning and likely an error further on if the dependency is required for compilation.

After that it will search for transitive dependencies. It does not pass these files to the compiler, but instead uses them to generate a list of files that need to be considered in subsequent build steps for things like generating license files, trust information, and suggested binding redirects. This step does consider the project's config file, and specifically uses its binding redirects to inform the list of transitive dependencies. It's important to note that building an exe will not consider its library's app.config files during the build, and a library's app.config will not change the way that library’s dll is produced.

The Runtime (CLR)

The CLR uses the config files to change the way it locates assemblies.

IIS

IIS will read elements of your web.config file to change the way your web app behaves. For example, caching characteristics.

Applications

Applications may manually retrieve configuration data from config files using the ConfigurationManager.

Tags:

Nuget