C# 如何让应用程序阅读<;运行时间>;从我的自定义app.config文件而不是从默认文件

C# 如何让应用程序阅读<;运行时间>;从我的自定义app.config文件而不是从默认文件,c#,.net,app-config,C#,.net,App Config,假设我正在创建一个名为ConsoleApp2的应用程序 由于我使用的某些第三方库,我的默认app.config文件生成的代码如下 <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4f

假设我正在创建一个名为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>
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "test.exe.config");
这(几乎)是完美的。虽然

请注意,(3)设置是从我的自定义配置文件中正确读取的。到目前为止还不错

现在将默认配置文件重命名为类似于_ConsoleApp2.exe.config的文件,然后再次运行该应用程序。您现在应该得到一个FileLoadException

那么,我如何告诉我的应用程序从我的自定义配置文件中读取
信息呢


根本原因 我寻求这个问题答案的原因如下:

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();

        }
    }
}
当我们发布应用程序时,我们将所有的.exe和.dll文件放在一个文件夹中,将我们的自定义配置文件(带有设置等)放在另一个文件夹中,我们的客户机在那里有类似的文件


在包含.exe和.dll文件的文件夹中,我们尽量少保留一些文件,因此,如果可能的话,我被要求找到一种方法来摆脱ConsoleApp2.exe.config。现在,由于前面提到的绑定是在该配置文件中编写的,所以我尝试将该信息移动到自定义配置文件中。。。但到目前为止,我还没有实现:绑定重定向总是试图从该控制台eapp2.exe.config读取,因此一旦我删除它,就会出现异常…

要正确处理不同的
.config
文件,您可以保留默认重定向来管理竞价重定向,并保留另一个用于应用程序参数。这样做看起来很棒

您还可以关闭自动绑定重定向生成并仅使用手工编制的app.config文件。这里有一个例子:

编辑 考虑到理由: 如果我理解,您根本不需要app.exe.config文件。 您已经设法在其他地方放置和读取自定义contant

只保留绑定重定向

您可以通过在运行时管理绑定重定向来摆脱它,就像这里所做的那样: 您还可以通过让代码查看配置文件来重新创建可配置的绑定解析器

我的两分钱在这里:这是可行的,但我认为不值得

编辑2 此解决方案看起来很有希望

Config transformation 如果您试图使用另一个(非本机)配置文件时出现问题,则您正试图找到“正确”替换它的解决方案。在我的回答中,我想退后一步,集中讨论你为什么要替换它。根据您在问题中描述的内容,您可以定义自定义应用程序设置。如果我理解正确,您计划将其链接到目标项目,将“Copy to output”属性设置为“Always”,然后将其放在应用程序附近

有一种方法可以转换现有(本机)配置文件,而不是复制新的配置文件,在您的示例中-
ConsoleApp2.exe.config
using。要实现这一点,请创建转换文件,并在其中仅声明要转换的部分,例如:

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <appSettings xdt:Transform="Replace">
    <add key="A" value="1"/>
    <add key="B" value="1"/>
    <add key="C" value="1"/>
  </appSettings>
</configuration>
<configuration>
    <appSettings>
        <add key="ClientSessionTimeout" value="100"
            xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
    </appSettings>
</configuration>

,您可以替换节、合并节、设置/删除属性等。您可以进行特定于环境(DEV/UAT/PROD)或特定于生成(Debug/Release)的转换
  • 可重用性:定义一次转换,并在所有需要的项目中重用它
  • 粒度:只声明所需内容,无需复制粘贴整个配置
  • 安全性:让nuget和msbuild管理“本机”配置文件(添加绑定重定向等)
  • 这种方法的唯一缺点是学习曲线:您需要学习语法,并知道如何将转换粘合到MSBuild中的配置

    .NET Core支持转换,即如何为web.config创建转换,但您可以将转换应用于任何配置

    如果您开发.NET应用程序(而不是.NETCore),那么我建议您看看

    有很多关于转换的资源和有用的blogbost,它的应用相当广泛。如果你有困难,请与我联系

    从我的观点来看,配置转换是一个正确的解决方案来实现你的目标,所以我强烈建议考虑它,而不是调整运行时。 外部化配置部分 如果您仍然希望将appSettings保留在公共位置,则可以使用属性外部化配置部分。有关详细信息,请检查并执行以下操作:

    // ConsoleApp2.exe.config:
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <connectionStrings configSource="../commonConfig/connections.config"/>
    </configuration>
    
    // connections.config:
    <?xml version="1.0" encoding="utf-8"?>
    <connectionStrings>
    <add name="MovieDBContext" 
       connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=aspnet-MvcMovie;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\Movies.mdf" 
       providerName="System.Data.SqlClient" 
    />
    </connectionStrings>
    
    //ConsoleApp2.exe.config:
    //connections.config:
    属性,该属性允许您合并另一个文件中的参数


    此选项允许您替换配置的某些部分,但不能替换整个内容本身。因此,如果您只需要appSettings,它是完全适用的-您只需将带有appSettings的配置文件放在与用户共享的公共位置,并将补丁配置文件(添加
    文件
    配置源
    属性)从该位置生成此节。如果您需要更多的节,则需要将它们提取为单独的文件。

    您可能正在寻找配置转换:

    背后的想法是,您可以在Visual Studio中创建多个配置,如配置管理器中的调试、发布、生产、测试……,以及默认配置文件和所谓的转换

    注意您可以在configuration manager中创建任意数量的配置。要添加新的配置,请单击解决方案配置(显示“调试”或“发布”的下拉列表),然后选择“配置管理器…”。打开它,您将看到当前所有现有配置的列表。下拉组合框“活动解决方案配置”并选择“
    ”以添加更多内容

    这些转换指定了使特定配置与默认配置不同的因素,因此您无需重复
    <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
      <appSettings xdt:Transform="Replace">
        <add key="A" value="1"/>
        <add key="B" value="1"/>
        <add key="C" value="1"/>
      </appSettings>
    </configuration>
    
    // ConsoleApp2.exe.config:
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <connectionStrings configSource="../commonConfig/connections.config"/>
    </configuration>
    
    // connections.config:
    <?xml version="1.0" encoding="utf-8"?>
    <connectionStrings>
    <add name="MovieDBContext" 
       connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=aspnet-MvcMovie;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\Movies.mdf" 
       providerName="System.Data.SqlClient" 
    />
    </connectionStrings>
    
    <configuration>
        <appSettings>
            <add key="ClientSessionTimeout" value="100"
                xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
        </appSettings>
    </configuration>
    
    <add key="UserIdForDebugging" xdt:Transform="Remove" xdt:Locator="Match(key)"/>