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>
これは、私のソリューションが1つのライブラリの異なるバージョンを参照するため、「このライブラリの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ファイルを1つのフォルダーに配置し、カスタム構成ファイル(設定などを含む)を別のフォルダーに配置します。クライアントには同様のファイルがあります。
.exeファイルと.dllファイルが含まれるフォルダーでは、できるだけ少なくしようとするため、可能であれば、ConsoleApp2.exe.configを削除する方法を見つけるように求められました。今、前述のバインディングはその構成ファイルに記述されているので、その情報をカスタム構成ファイルに移動しようとしましたが、これまでのところ達成できませんでした:バインディングリダイレクトは常にそのConsoleApp2.exeから読み取られます.configなので、削除するとすぐに例外が発生します...