让我们说我正在创建一个名为 ConsoleApp2 的应用。
由于我正在使用某些第三方库,因此我的默认app.config文件正在生成类似
的代码<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>
那是因为我的解决方案引用了一个库的不同版本,所以它需要告诉所有人:“ 嘿,如果您要查找该库的任何 oldVersion ,只需使用 newVersion ”。没关系。
问题是我想定义一个单独的配置文件“ test.exe.config”,在其中进行一些设置并摆脱自动生成的设置。
为了向我的应用程序介绍新的配置文件,我正在使用类似的代码
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE","test.exe.config");
而且(几乎)完美运行。我在此处写了“ 几乎”,因为尽管正确地阅读了<appSettings>
部分,但在我的自定义配置文件中并未查看<runtime>
部分,但是应用看上去而是在默认配置文件中显示该文件,这是一个问题,因为我希望以后可以删除该文件。
那么,如何告诉我的应用程序也从我的自定义配置文件中读取<runtime>
信息?
如何重现问题
重现我的问题的简单示例如下:
使用单个类创建名为 Classlibrary2 ( .Net Framework v4.6 )的库,如下所示:
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; }
}
}
请注意对 Newtonsoft 软件包的引用。库中安装的是 v10.0.2 。
现在使用名为 Program 的类创建一个名为 ConsoleApp2 ( .Net Framework v4.6 )的控制台应用程序,其内容如下:
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();
}
}
}
此应用程序还应该安装了 Newtonsoft ,但安装的版本是 v12.0.3 。
以“调试”模式构建应用程序。然后,在文件夹 ConsoleApp2 / ConsoleApp2 / bin / Debug 中创建一个名为 test.exe.config 的文件,其中包含以下内容
<?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>
,请注意,在同一 Debug 文件夹中,还存在默认配置文件 ConsoleApp2.exe.config ,其内容类似于
<?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>
这时,如果您运行该应用程序,它将毫无问题地进行编译,您应该会看到一个类似
的控制台。请注意,正确地从我的自定义配置文件中读取了(3)设置。到目前为止一切顺利...
现在将默认配置文件重命名为 _ConsoleApp2.exe.config ,然后再次运行该应用程序。您现在应该得到一个 FileLoadException 。
再次,我如何告诉我的应用程序从我的自定义配置文件中读取<runtime>
信息?
理性
我正在寻找这个问题的答案的原因如下:
发布应用程序时,我们将所有.exe和.dll文件放在一个文件夹中,而将自定义配置文件(带有设置等)放在另一个文件夹中,客户端的文件与此类似。
在包含.exe和.dll文件的文件夹中,我们尝试尽可能地少保存文件,因此,我被要求找到一种摆脱该 ConsoleApp2.exe.config 的方法。现在,由于上述绑定是写在该配置文件中的,所以我只是尝试将这些信息移到我们的自定义配置文件中...但是到目前为止,我仍未能实现:总是尝试从该中读取绑定重定向ConsoleApp2.exe.config ,因此,一旦我将其删除,我就会获得例外...