Angenommen, ich erstelle eine App namens ConsoleApp2 .
Aufgrund einiger Bibliotheken von Drittanbietern, die ich verwende, generiert meine Standarddatei app.config Code wie
<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>
Das liegt daran, dass meine Lösung auf verschiedene Versionen einer Bibliothek verweist. Daher muss sie allen mitteilen: " Hey, wenn Sie nach einer alten Version dieser Bibliothek suchen , verwenden Sie einfach newVersion. " Und das ist in Ordnung.
Das Problem ist, dass ich eine separate Konfigurationsdatei "test.exe.config" definieren möchte, in der ich einige Einstellungen habe und die automatisch generierte entfernen möchte.
Um meine App über die neue Konfigurationsdatei zu informieren, verwende ich Code wie
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "test.exe.config");
Und das funktioniert (fast) perfekt. Und ich habe dort " fast " geschrieben, da der <appSettings>
Abschnitt zwar korrekt gelesen wird, der <runtime>
Abschnitt jedoch nicht in meiner benutzerdefinierten Konfigurationsdatei angezeigt wird, sondern die App ihn stattdessen in der Standardkonfigurationsdatei sucht, was ein Problem ist, da ich dies möchte in der Lage sein, diese später zu löschen.
Wie kann ich meine Anwendung anweisen, auch die <runtime>
Informationen aus meiner benutzerdefinierten Konfigurationsdatei zu lesen ?
So reproduzieren Sie das Problem
Ein einfaches Beispiel zur Reproduktion meines Problems lautet wie folgt:
Erstellen Sie eine Bibliothek mit dem Namen ClassLibrary2 ( .Net Framework v4.6 ) mit einer einzelnen Klasse wie folgt
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; }
}
}
Beachten Sie den Verweis auf das Newtonsoft- Paket. Die in der Bibliothek installierte Version ist 10.0.2 .
Erstellen Sie nun eine Konsolenanwendung mit dem Namen ConsoleApp2 ( .Net Framework v4.6 ) mit einer Klasse namens Program, deren Inhalt einfach wie folgt lautet:
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();
}
}
}
Diese Anwendung sollte auch Newtonsoft installiert haben , jedoch in einer anderen Version v12.0.3 .
Erstellen Sie die Anwendung im Debug-Modus. Erstellen Sie dann im Ordner ConsoleApp2 / ConsoleApp2 / bin / Debug eine Datei mit dem Namen test.exe.config mit folgendem Inhalt
<?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>
und beachten Sie, dass sich in demselben Debug- Ordner auch die Standardkonfigurationsdatei ConsoleApp2.exe.config mit einem Inhalt wie befindet
<?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>
Wenn Sie die Anwendung an diesem Punkt ausführen, wird sie problemlos kompiliert, und Sie sollten eine Konsole wie diese sehen
Beachten Sie, dass die (3) Einstellungen korrekt aus meiner benutzerdefinierten Konfigurationsdatei gelesen wurden. So weit, ist es gut...
Benennen Sie nun die Standardkonfigurationsdatei in _ConsoleApp2.exe.config um und führen Sie die Anwendung erneut aus. Sie sollten jetzt eine FileLoadException erhalten .
Wie kann ich meine Anwendung anweisen, die <runtime>
Informationen aus meiner benutzerdefinierten Konfigurationsdatei zu lesen ?
Begründung
Der Grund, warum ich eine Antwort auf diese Frage suche, ist folgender:
Wenn wir unsere Anwendung freigeben, legen wir alle EXE- und DLL-Dateien in einem Ordner und unsere benutzerdefinierte Konfigurationsdatei (mit Einstellungen usw.) in einem anderen Ordner ab, in dem unsere Clients ähnliche Dateien haben.
In dem Ordner mit den EXE- und DLL-Dateien versuchen wir, so wenig wie möglich zu behalten, daher wurde ich gebeten, einen Weg zu finden, um diese ConsoleApp2.exe.config nach Möglichkeit zu entfernen . Da die oben genannten Bindungen in diese Konfigurationsdatei geschrieben wurden, habe ich nur versucht, diese Informationen in unsere benutzerdefinierte Konfigurationsdatei zu verschieben ... aber bisher habe ich es nicht geschafft: Die Bindungsumleitungen werden immer versucht, von dieser ConsoleApp2.exe gelesen zu werden .config , sobald ich es entferne, bekomme ich Ausnahmen ...
<runtime>
Abschnitt aus einer anderen Konfiguration anzuwenden , aber das Problem tritt aufgrund der Art und Weise auf, wie Sie die allgemeine Konfiguration verwalten. Wenn Sie die allgemeine Konfiguration auf andere Weise verwalten, ist dieses Problem nicht mehr relevant. Bitte überprüfen Sie meine Antwort und ziehen Sie in Betracht, Konfigurationstransformationen zu verwenden, anstatt die Laufzeit zu optimieren.