Dec*_*oth 9 .net c# app-config
假设我正在创建一个名为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>
Run Code Online (Sandbox Code Playgroud)
那是因为我的解决方案引用了一个库的不同版本,所以它需要告诉大家:“嘿,如果你要找这个库的任何旧版本,就用新版本”。没关系。
问题是我想定义一个单独的配置文件“test.exe.config”,在那里我有一些设置并摆脱自动生成的设置。
为了告诉我的应用程序有关新配置文件的信息,我使用了如下代码
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "test.exe.config");
Run Code Online (Sandbox Code Playgroud)
这(几乎)完美地工作。我在那里写了“几乎”,因为虽然该<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; }
}
}
Run Code Online (Sandbox Code Playgroud)
请注意对Newtonsoft软件包的引用。安装在库中的是v10.0.2。
现在创建一个名为ConsoleApp2 ( .Net Framework v4.6 )的控制台应用程序,其中包含一个名为Program的类,其内容如下:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
此应用程序也应安装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>
Run Code Online (Sandbox Code Playgroud)
请注意,在同一个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>
Run Code Online (Sandbox Code Playgroud)
如果此时您运行该应用程序,它将毫无问题地编译,您应该会看到一个控制台,如
请注意,(3) 设置是从我的自定义配置文件中正确读取的。到现在为止还挺好...
现在将默认配置文件重命名为_ConsoleApp2.exe.config并再次运行该应用程序。你现在应该得到一个FileLoadException。
再说一次,我如何告诉我的应用程序<runtime>从我的自定义配置文件中读取信息?
我正在寻找这个问题的答案的原因如下:
当我们发布我们的应用程序时,我们将所有 .exe 和 .dll 文件放在一个文件夹中,并将我们的自定义配置文件(带有设置等)放在另一个文件夹中,我们的客户有类似的文件。
在包含 .exe 和 .dll 文件的文件夹中,我们尝试保留尽可能少的内容,因此我被要求找到一种方法,如果可能的话,摆脱那个ConsoleApp2.exe.config。现在,由于上述绑定是在该配置文件中写入的,我只是尝试将该信息移动到我们的自定义配置文件中......但到目前为止我未能实现:绑定重定向总是试图从那个ConsoleApp2.exe读取.config,所以一旦我删除它,我就会得到例外......
您可能正在寻找配置转换:
背后的想法是您在 Visual Studio 中创建多个配置,如配置管理器中的调试、发布、生产、测试……以及默认配置文件和所谓的转换。
请注意,您可以在配置管理器中创建任意数量的配置。要添加新配置,请单击解决方案配置(显示“调试”或“发布”的下拉列表),然后选择“配置管理器...”。打开它,您会看到所有当前现有配置的列表。下拉组合框“活动解决方案配置”并选择“ <New...>”以添加更多。
这些转换指定了使特定配置与默认配置不同的原因 - 因此您无需重复在默认配置中已指定的内容,而只需提及差异,例如:
<configuration>
<appSettings>
<add key="ClientSessionTimeout" value="100"
xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
</appSettings>
</configuration>
Run Code Online (Sandbox Code Playgroud)
它通过其键找到相关设置,ClientSessionTimeout并100通过替换配置文件中的原始值来设置其值(这就是附加转换属性的xdt:Transform="SetAttributes" xdt:Locator="Match(key)"含义)。您还可以指定删除现有设置(通过指定xdt:Transform="Remove"代替),例如
<add key="UserIdForDebugging" xdt:Transform="Remove" xdt:Locator="Match(key)"/>
Run Code Online (Sandbox Code Playgroud)
将删除一个应该只用于调试而不是用于发布的用户 ID(要了解有关可用选项的更多信息,请查看此处- 针对 Web.config 进行了描述,但也适用于 App.config)。
除了App.Config文件之外,每个配置都有一个文件,即App.Debug.Config用于调试、App.Release.Config用于发布等。Visual Studio 可帮助您创建它们。
我已经在这里和那里在 StackOverflow 中创建了答案,其中详细描述了它,请看一看。
如果在 Visual Studio 中显示它们时遇到问题,请查看此处。
关于你的理由:
转换通过将转换文件应用到默认配置文件来创建完整的配置文件。生成的文件被编译并放入“bin”文件夹 - 与其他编译文件一起。因此,如果您选择了配置“Release”,那么包括转换后的配置文件在内的所有文件都会被编译到“bin\Release”中。
并且配置文件的命名就像exe文件加上末尾附加的“.config”(换句话说,二进制文件夹中没有“.Release.config”,而是创建了“MySuperCoolApp.exe.config”-对于应用程序“MySuperCoolApp.exe”)。
同样,其他配置也是如此——每个配置在“bin”内创建一个子文件夹——如果您使用脚本,则可以$(TargetDir)在构建后事件中引用该子文件夹。
为了正确使用不同的.config文件,您可以保留默认文件来管理出价重定向,另一文件用于您的应用程序参数。为此,在运行时更改默认的 app.config看起来很棒。
您还可以关闭自动绑定重定向生成并仅使用手工制作的 app.config 文件。这里有一个例子:Need a way to reference 2 different versions of the same 3rd party DLL
编辑 考虑到基本原理:如果我理解的话,你根本不需要 app.exe.config 文件。您已经设法在其他地方放置和读取自定义内容。
仅保留绑定重定向。
您可以通过在运行时管理绑定重定向来摆脱它,就像这里所做的那样: https: //stackoverflow.com/a/32698357/361177 您还可以通过让代码查看配置文件来重新创建可配置的绑定解析器。
我的两分钱是:这是可行的,但我认为不值得。
编辑2 这个解决方案看起来很有前途/sf/answers/1995033421/
| 归档时间: |
|
| 查看次数: |
2047 次 |
| 最近记录: |