99 Stimmen

Variablen in app.config/web.config

Ist es möglich, etwas wie das Folgende in der app.config o web.config Dateien?

<appSettings>
 <add key="MyBaseDir" value="C:\MyBase" />
 <add key="Dir1" value="[MyBaseDir]\Dir1"/>
 <add key="Dir2" value="[MyBaseDir]\Dir2"/>
</appSettings>

Ich möchte dann in meinem Code auf Dir2 zugreifen, indem ich einfach sage:

 ConfigurationManager.AppSettings["Dir2"]

Dies wird mir helfen, wenn ich meine Anwendung auf verschiedenen Servern und an verschiedenen Standorten installiere, da ich nur EINEN Eintrag in meiner gesamten Anwendung ändern muss. app.config . (Ich weiß, dass ich die gesamte Verkettung im Code verwalten kann, aber ich bevorzuge diesen Weg).

1 Stimmen

Ich glaube, er meint damit die Definition von Variablen, die in appSettings-Schlüsseln direkt in den Konfigurationsdateien verwendet werden sollen.

1 Stimmen

Ich habe auch die Verwendung der XML <!ENTITY>-Deklaration ausprobiert, aber sie wird aufgrund der Art und Weise, wie MS web.config-Dateien behandelt, nicht unterstützt.

0 Stimmen

Vielen Dank für Ihre Bemühungen. Ich ziehe es vor, keinen Code zu ändern. Der Code enthält bereits eine Anweisung, die lautet: string dir2=ConfigurationManager.AppSettings["Dir2"]. Ich möchte nur die app.config bereinigen, in der jetzt value=" steht. D:\blahdir\Dir2 " anstelle von value="[MyBaseDir] \Dir2 "

0voto

Andrew Barrett Punkte 19351

Ich kämpfe ein bisschen mit dem, was Sie wollen, aber Sie können eine Überschreibungsdatei zu den App-Einstellungen hinzufügen, dann haben, dass Überschreibungsdatei auf eine pro Umgebung Basis festgelegt.

<appSettings file="..\OverrideSettings.config">

0voto

cjk Punkte 44394

Für die Einführung von Produkten, bei denen wir viele Elemente mit ähnlichen Werten konfigurieren müssen, verwenden wir kleine Konsolenanwendungen, die das XML lesen und anhand der übergebenen Parameter aktualisieren. Diese werden dann vom Installationsprogramm aufgerufen, nachdem es den Benutzer nach den erforderlichen Informationen gefragt hat.

0voto

Rich Punkte 388

Ich würde empfehlen, der Lösung von Matt Hamsmith zu folgen. Wenn es ein Problem bei der Implementierung ist, warum dann nicht eine Erweiterungsmethode erstellen, die dies im Hintergrund in der AppSettings-Klasse implementiert?

Etwa so:

    public static string GetValue(this NameValueCollection settings, string key)
    {

    }

Innerhalb der Methode durchsuchen Sie die DictionaryInfoConfigSection mit Linq und geben den Wert mit dem passenden Schlüssel zurück. Sie müssen allerdings die Konfigurationsdatei aktualisieren, etwa in dieser Form:

<appSettings>
  <DirectoryMappings>
    <DirectoryMap key="MyBaseDir" value="C:\MyBase" />
    <DirectoryMap key="Dir1" value="[MyBaseDir]\Dir1"/>
    <DirectoryMap key="Dir2" value="[MyBaseDir]\Dir2"/>
  </DirectoryMappings>
</appSettings>

0voto

anhoppe Punkte 3769

Ich habe diese Lösung gefunden:

  1. In der Anwendung Settings.settings habe ich eine Variable ConfigurationBase definiert (mit type=string Scope=Application)
  2. Ich habe eine Variable in die Zielattribute in der Settings.settings eingefügt, alle diese Attribute mussten auf Scope=User gesetzt werden
  3. In der app.xaml.cs lese ich den Wert aus, wenn die ConfigurationBase
  4. In der app.xaml.cs habe ich alle Variablen durch den ConfigurationBase-Wert ersetzt. Um die Werte zur Laufzeit zu ersetzen, mussten die Attribute auf Scopr=User gesetzt werden

Ich bin nicht wirklich zufrieden mit dieser Lösung, weil ich alle Attribute manuell ändern muss, wenn ich ein neues hinzufüge, muss ich es in der app.xaml.cs berücksichtigen.

Hier ein Codeschnipsel aus der App.xaml.cs:

string configBase = Settings.Default.ConfigurationBase;
Settings.Default.CommonOutput_Directory = Settings.Default.CommonOutput_Directory.Replace("${ConfigurationBase}", configBase);

UPDATE

Habe gerade eine Verbesserung gefunden (wieder ein Codeschnipsel aus der app.xaml.cs):

string configBase = Settings.Default.ConfigurationBase;

foreach (SettingsProperty settingsProperty in Settings.Default.Properties)
{
    if (!settingsProperty.IsReadOnly && settings.Default[settingsProperty.Name] is string)
    {
        Settings.Default[settingsProperty.Name] = ((string)Settings.Default[settingsProperty.Name]).Replace("${ConfigurationBase}", configBase);
    }
}

Jetzt funktionieren die Ersetzungen für alle Attribute in meinen Einstellungen, die Type=string und Scope=User haben. Ich glaube, ich mag es so.

UPDATE2

Offenbar ist die Einstellung Scope=Application bei der Ausführung über die Eigenschaften nicht erforderlich.

0voto

StormChild Punkte 1

Drei mögliche Lösungen

Ich weiß, dass ich zu spät zur Party komme, aber ich habe mich umgesehen, ob es neue Lösungen für das Problem der variablen Konfigurationseinstellungen gibt. Es gibt ein paar Antworten, die die Lösungen, die ich in der Vergangenheit verwendet haben, berühren, aber die meisten scheinen ein bisschen verworren. Ich dachte, ich schaue mir meine alten Lösungen an und fasse die Implementierungen zusammen, damit es anderen helfen kann, die mit demselben Problem kämpfen.

Für dieses Beispiel habe ich die folgende Einstellung in einer Konsolenanwendung verwendet:

<appSettings>
    <add key="EnvironmentVariableExample" value="%BaseDir%\bin"/>
    <add key="StaticClassExample" value="bin"/>
    <add key="InterpollationExample" value="{0}bin"/>
  </appSettings>

1. Umgebungsvariablen verwenden

Ich glaube, Autocro autocro's Antwort berührte es. Ich tue nur eine Implementierung, die beim Erstellen oder Debuggen ausreichen sollte, ohne dass Visual Studio geschlossen werden muss. Ich habe diese Lösung zurück in den Tag verwendet ...

  • Erstellen Sie ein Pre-Build-Ereignis, das die MSBuild-Variablen verwenden wird

    Warnung: Verwenden Sie eine Variable, die nicht einfach ersetzt werden kann, also verwenden Sie Ihren Projektnamen oder etwas Ähnliches als Variablennamen.

    SETX BaseDir "$(ProjectDir)"

  • Setzen Sie die Variablen zurück; verwenden Sie dazu etwas wie das Folgende:

    Aktualisieren von Umgebungsvariablen auf Stack Overflow

  • Verwenden Sie die Einstellung in Ihrem Code:

'

private void Test_Environment_Variables()
{
    string BaseDir = ConfigurationManager.AppSettings["EnvironmentVariableExample"];
    string ExpandedPath = Environment.ExpandEnvironmentVariables(BaseDir).Replace("\"", ""); //The function addes a " at the end of the variable
    Console.WriteLine($"From within the C# Console Application {ExpandedPath}");
}

'

2. Verwenden Sie die String-Interpolation:

  • Verwenden Sie die Funktion string.Format()

`

private void Test_Interpollation()
{
    string ConfigPath = ConfigurationManager.AppSettings["InterpollationExample"];
    string SolutionPath = Path.GetFullPath(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"..\..\"));
    string ExpandedPath = string.Format(ConfigPath, SolutionPath.ToString());
    Console.WriteLine($"Using old interpollation {ExpandedPath}");
}

`

3. Verwendung einer statischen Klasse. Dies ist die Lösung, die ich meistens verwende.

  • Die Umsetzung

`

private void Test_Static_Class()
{
    Console.WriteLine($"Using a static config class {Configuration.BinPath}");
}

`

  • Die statische Klasse

`

static class Configuration
{
    public static string BinPath
    {
        get
        {
            string ConfigPath = ConfigurationManager.AppSettings["StaticClassExample"];
            string SolutionPath = Path.GetFullPath(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"..\..\"));
            return SolutionPath + ConfigPath;
        }
    }
}

`

Projekt-Code:

App.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
  <appSettings>
    <add key="EnvironmentVariableExample" value="%BaseDir%\bin"/>
    <add key="StaticClassExample" value="bin"/>
    <add key="InterpollationExample" value="{0}bin"/>
  </appSettings>
</configuration>

Programm.cs

using System;
using System.Configuration;
using System.IO;

namespace ConfigInterpollation
{
    class Program
    {
        static void Main(string[] args)
        {
            new Console_Tests().Run_Tests();
            Console.WriteLine("Press enter to exit");
            Console.ReadLine();
        }        
    }

    internal class Console_Tests
    {
        public void Run_Tests()
        {
            Test_Environment_Variables();
            Test_Interpollation();
            Test_Static_Class();
        }
        private void Test_Environment_Variables()
        {
            string ConfigPath = ConfigurationManager.AppSettings["EnvironmentVariableExample"];
            string ExpandedPath = Environment.ExpandEnvironmentVariables(ConfigPath).Replace("\"", "");
            Console.WriteLine($"Using environment variables {ExpandedPath}");
        }

        private void Test_Interpollation()
        {
            string ConfigPath = ConfigurationManager.AppSettings["InterpollationExample"];
            string SolutionPath = Path.GetFullPath(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"..\..\"));
            string ExpandedPath = string.Format(ConfigPath, SolutionPath.ToString());
            Console.WriteLine($"Using interpollation {ExpandedPath}");
        }

        private void Test_Static_Class()
        {
            Console.WriteLine($"Using a static config class {Configuration.BinPath}");
        }
    }

    static class Configuration
    {
        public static string BinPath
        {
            get
            {
                string ConfigPath = ConfigurationManager.AppSettings["StaticClassExample"];
                string SolutionPath = Path.GetFullPath(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"..\..\"));
                return SolutionPath + ConfigPath;
            }
        }
    }
}

Veranstaltung vor dem Bau:

Projekteinstellungen -> Build-Ereignisse

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X