Let us say i am creating an app called ConsoleApp2.
Because of some third party libraries i am using, my default app.config file is generating code like
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
That is because my solution references different versions of one library, so it needs to tell everyone: "Hey, if you look for any oldVersion of this library, just use newVersion". And that is all right.
The problem is that i want to define a separate config file "test.exe.config" where i have some settings and get rid of the automatically generated one.
In order to tell my App about the new config file i am using code like
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "test.exe.config");
And that works (almost) perfectly. And i wrote there "almost" since although the <appSettings>
section is being read correctly, the <runtime>
section is not being looked at in my custom config file, but the App looks for it in the default config file instead, which is a problem since i want to be able to delete that one later.
So, how can i tell my Application to read also the <runtime>
information from my custom config file?
How to reproduce the issue
A simple sample to reproduce my issue is as follows:
Create a library called ClassLibrary2 (.Net Framework v4.6) with a single class as follows
using Newtonsoft.Json.Linq;
using System;
namespace ClassLibrary2
{
public class Class1
{
public Class1()
{
var json = new JObject();
json.Add("Succeed?", true);
Reash = json.ToString();
}
public String Reash { get; set; }
}
}
Note the reference to Newtonsoft package. The one installed in the library is v10.0.2.
Now create a Console Application called ConsoleApp2 (.Net Framework v4.6) with a class called Program which content is simply as follows:
using System;
using System.Configuration;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "test.exe.config");
var AppSettings = ConfigurationManager.AppSettings;
Console.WriteLine($"{AppSettings.Count} settings found");
Console.WriteLine($"Calling ClassLibrary2: {Environment.NewLine}{new ClassLibrary2.Class1().Reash}");
Console.ReadLine();
}
}
}
This Application should have installed also Newtonsoft, but in a different version v12.0.3.
Build the Application in Debug mode. Then, in the folder ConsoleApp2/ConsoleApp2/bin/Debug create a file called test.exe.config with following content
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<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-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<appSettings>
<add key="A" value="1"/>
<add key="B" value="1"/>
<add key="C" value="1"/>
</appSettings>
</configuration>
and note that in that same Debug folder there is also the default config file ConsoleApp2.exe.config with a content like
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<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-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
If a this point you run the application it will compile with no problems and you should see a Console like
Note that the (3) settings were read from my custom config file correctly. So far so good...
Now rename the default config file to something like _ConsoleApp2.exe.config and run again the application. You should now get a FileLoadException.
So again, how can i tell my Application to read the <runtime>
information from my custom config file?
Rationale
The reason i am looking an answer to this question is as follows:
When we release our application, we put all the .exe and .dll files in one folder and our custom config file (with settings, etc) in another, where our clients have similar files.
In the folder with the .exe and .dll files we try to keep as little as possible so i was asked to find a way to get rid of that ConsoleApp2.exe.config if possible. Now, since the aforementioned bindings were written in that config file, i just tried moving that information to our custom config file... but so far i have failed to achieve: the binding redirects are always tried to be read from that ConsoleApp2.exe.config, so as soon as i remove it i get exceptions...