Frage

Ist es möglich ist, so etwas wie die folgenden in den app.config oder web.config Dateien zu tun?

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

Ich mag dann Dir2 in meinem Code zugreifen, indem er einfach zu sagen:

 ConfigurationManager.AppSettings["Dir2"]

Das wird mir helfen, wenn ich meine Anwendung in verschiedenen Servern und Standorten installiert werden, wobei ich nur einen Eintrag in meinem ganzen app.config ändern muß. (Ich weiß, dass ich die ganze Verkettung in Code verwalten kann, aber ich ziehe es auf diese Art und Weise).

War es hilfreich?

Lösung

Gute Frage.

Ich glaube nicht, es gibt. Ich glaube, es wäre recht gut bekannt gewesen, wenn es ein einfacher Weg, und ich sehe, dass Microsoft einen Mechanismus in Visual Studio 2010 für die Bereitstellung von verschiedenen Konfigurationsdateien für die Bereitstellung und Test erstellt.

Mit dieser sagte jedoch, Ich habe, dass Sie eine Art Platzhalter im ConnectionStrings Abschnitt gefunden genannt haben „| Datadirectory |“. Vielleicht könnten Sie einen Blick auf das, was es bei der Arbeit ist ...

Hier ist ein Stück aus machine.config zeigt es:

 <connectionStrings>
    <add
        name="LocalSqlServer"
        connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
        providerName="System.Data.SqlClient"
    />
 </connectionStrings>

Andere Tipps

Ein etwas komplizierter, aber weitaus flexibler, Alternative ist, eine Klasse zu erstellen, die einen Konfigurationsabschnitt darstellt. In Ihrer app.config / web.config-Datei können Sie diese:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <!-- This section must be the first section within the <configuration> node -->
    <configSections>
        <section name="DirectoryInfo" type="MyProjectNamespace.DirectoryInfoConfigSection, MyProjectAssemblyName" />
    </configSections>

    <DirectoryInfo>
        <Directory MyBaseDir="C:\MyBase" Dir1="Dir1" Dir2="Dir2" />
    </DirectoryInfo>
</configuration>

Dann in Ihrem .NET-Code (Ich werde in meinem Beispiel verwenden C #), zwei Klassen wie folgt erstellen:

using System;
using System.Configuration;

namespace MyProjectNamespace {

    public class DirectoryInfoConfigSection : ConfigurationSection {

        [ConfigurationProperty("Directory")]
        public DirectoryConfigElement Directory {
            get {
                return (DirectoryConfigElement)base["Directory"];
            }
    }

    public class DirectoryConfigElement : ConfigurationElement {

        [ConfigurationProperty("MyBaseDir")]
        public String BaseDirectory {
            get {
                return (String)base["MyBaseDir"];
            }
        }

        [ConfigurationProperty("Dir1")]
        public String Directory1 {
            get {
                return (String)base["Dir1"];
            }
        }

        [ConfigurationProperty("Dir2")]
        public String Directory2 {
            get {
                return (String)base["Dir2"];
            }
        }
        // You can make custom properties to combine your directory names.
        public String Directory1Resolved {
            get {
                return System.IO.Path.Combine(BaseDirectory, Directory1);
            }
        }
    }
}

Schließlich in Ihren Programmcode können Sie Ihre app.config Variablen zugreifen, werden neue Klassen, die auf diese Weise:

DirectoryInfoConfigSection config =
  (DirectoryInfoConfigSection)ConfigurationManager.GetSection("DirectoryInfo");
String dir1Path = config.Directory.Directory1Resolved;  // This value will equal "C:\MyBase\Dir1"

Sie erreichen kann meine Expansive Bibliothek: http://nuget.org/List/Packages/Expansive Quelle finden Sie hier: https://github.com/anderly/Expansive

Ich dachte, ich sah nur diese Frage.

Kurz gesagt, nein, gibt es keine variable Interpolation innerhalb einer Anwendungskonfiguration.

Sie haben zwei Möglichkeiten

  1. Sie können Ihre eigene Rolle Variablen zur Laufzeit ersetzen
  2. bei der Erstellung, massieren Sie die Anwendungskonfiguration auf die speziellen Besonderheiten der Zieleinsatzumgebung. Einige Einzelheiten hierzu finden Sie unter Umgang mit der Konfiguration-Alptraum

Sie haben ein paar Optionen. Man könnte dies mit einem Build / deploy Schritt der Konfigurationsdatei bearbeiten würde Ihre Variablen mit dem richtigen Wert zu ersetzen.

Eine andere Möglichkeit wäre eine eigene Konfigurationsbereich zu definieren, die diese unterstützt. Zum Beispiel vorstellen, diese xml:

<variableAppSettings>
 <variables>
    <add key="@BaseDir" value="c:\Programs\Widget"/>
 </variables>
 <appSettings>
    <add key="PathToDir" value="@BaseDir\Dir1"/>
 </appSettings>
</variableAppSettings>

Jetzt würden Sie diese mithilfe von benutzerdefinierten Konfigurationsobjekte implementieren, die die Variablen für Sie zur Laufzeit ersetzen würde behandeln.

Normalerweise habe ich am Ende eine statische Klasse mit Eigenschaften Schreiben jeden der Einstellungen meines web.config zugreifen zu können.

public static class ConfigManager 
{
    public static string MyBaseDir
    {
        return ConfigurationManager.AppSettings["MyBaseDir"].toString();
    }

    public static string Dir1
    {
        return MyBaseDir + ConfigurationManager.AppSettings["Dir1"].toString();
    }

}

In der Regel, das tue ich auch Typkonvertierungen, wenn sie in dieser Klasse erforderlich. Es ermöglicht einen typisierte Zugriff auf Ihre Konfiguration zu haben, und wenn Einstellungen zu ändern, können Sie sie nur an einer Stelle bearbeiten.

Normalerweise mit dieser Klasse Einstellungen zu ersetzen ist relativ einfach und bietet eine viel größere Wartbarkeit.

Sie können für dieses Szenario Umgebungsvariablen in Ihrem app.config verwenden Sie beschreiben

<configuration>
  <appSettings>
    <add key="Dir1" value="%MyBaseDir%\Dir1"/>
  </appSettings>
</configuration>

Dann können Sie leicht den Weg bekommen:

var pathFromConfig = ConfigurationManager.AppSettings["Dir1"];
var expandedPath = Environment.ExpandEnvironmentVariables(pathFromConfig);

Innerhalb <appSettings> Sie Anwendungsschlüssel erstellen können,

<add key="KeyName" value="Keyvalue"/>

Später können Sie diese Werte zugreifen können:

ConfigurationManager.AppSettings["Keyname"]

Ich würde vorschlagen, Sie DslConfig . Mit DslConfig können Sie hierarchische Konfigurationsdateien von Global Config Config pro Server-Host verwenden pro Anwendung config auf jedem Server-Host (siehe AppSpike).
Wenn dies für Sie zu kompliziert ist, können Sie einfach die globale config Variables.var
Konfigurieren Sie einfach in Varibales.var

baseDir = "C:\MyBase"
Var["MyBaseDir"] = baseDir
Var["Dir1"] = baseDir + "\Dir1"
Var["Dir2"] = baseDir + "\Dir2"

und nutzen Sie die Config-Werte mit

Configuration config = new DslConfig.BooDslConfiguration()
config.GetVariable<string>("MyBaseDir")
config.GetVariable<string>("Dir1")
config.GetVariable<string>("Dir2")

Ich glaube nicht, Sie deklarieren und Variablen verwenden können appSettings Schlüssel innerhalb einer Konfigurationsdatei zu definieren. Ich habe immer Verkettungen in Code wie Sie es geschafft.

Ich kämpfe ein bisschen mit dem, was Sie wollen, aber Sie können eine Überschreibungsdatei zu den App-Einstellungen dann außer Kraft Datei auf einer pro-Umgebung Basis festgelegt hat hinzuzufügen.

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

Für Produkte, Ausrollen, wo wir eine Menge von Elementen mit ähnlichen Werten konfigurieren müssen, verwenden wir kleine Konsole-Anwendungen, die die XML-und Update lesen auf der Grundlage der übergebenen Parameter in. Diese werden dann vom Installer aufgerufen, nachdem es die gefragt Benutzer für die erforderlichen Informationen ein.

würde ich folgenden Matt Hamsmith Lösung empfehlen. Wenn es ein Problem zu implementieren ist, warum dann nicht eine Erweiterungsmethode erstellen, die diese im Hintergrund auf der AppSettings-Klasse implementiert?

So etwas wie:

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

    }

Im Innern der Methode, die Sie durch die DictionaryInfoConfigSection suchen Linq verwenden und den Wert mit dem passenden Schlüssel zurück. Sie werden allerdings die Konfigurationsdatei aktualisieren müssen, um etwas in dieser Richtung:

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

Ich kam mit dieser Lösung:

  1. In der Anwendung Settings.settings ich eine Variable ConfigurationBase definiert (mit type = String Scope = Application)
  2. ich eine Variable eingeführt in das Ziel in den Settings.settings Attribute, all diese Attribute mussten Scope gesetzt werden = Benutzer
  3. In der App.xaml.cs las ich den Wert, wenn die ConfigurationBase
  4. In der App.xaml.cs ersetzt ich alle Variablen mit dem ConfigurationBase Wert. Um die Werte zur Laufzeit ersetzen mußten die Attribute Scopr = Benutzer
  5. gesetzt werden

Ich bin nicht wirklich glücklich mit dieser Lösung, weil ich ändern müssen alle manuell Attribute, wenn ich ein neues füge ich es in den App.xaml.cs zu betrachten haben.

Hier ist ein Code-Schnipsel aus dem App.xaml.cs:

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

UPDATE

hätte gerade eine Verbesserung (wieder einen Code-Schnipsel 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);
    }
}

Nun arbeiten die Ersetzungen für alle Attribute in meinen Einstellungen, die Type = String und Scope = Benutzer haben. Ich glaube, ich mag es auf diese Weise.

UPDATE2

Offenbar Einstellung Scope = Anwendung nicht erforderlich ist, wenn sie über die Eigenschaften ausgeführt wird.

Drei mögliche Lösungen

  

Ich weiß, ich komme zu spät zur Party, ich habe gefreut, wenn es neue Lösungen Problem auf das variablen Konfigurationseinstellungen sind. Es gibt ein paar Antworten, die die Lösungen berühren ich in der Vergangenheit verwendet haben, aber die meisten scheinen ein wenig gewunden. Ich dachte, ich an meiner alten Lösung aussehen würde und die Implementierungen zusammen, so dass sie Menschen helfen könnten, die mit dem gleichen Problem zu kämpfen hat.

Für dieses Beispiel habe ich die folgende App 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. Verwenden von Umgebungsvariablen

  

Ich glaube, autocro autocro Antwort auf sie berührt. Ich mache nur eine Implementierung, die ausreichen sollte beim Bau oder Debuggen ohne Visual Studio schließen zu müssen. Ich habe diese Lösung wieder in den Tag verwendet ...

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

    verwenden
      

    . Achtung: eine Variable verwenden, die nicht leicht ersetzt werden, so Projektnamen oder etwas ähnliches als Variablennamen verwenden

    SETX BaseDir "$(ProjectDir)"

  • Variablen zurücksetzen; mit so etwas wie folgt aus:

    Aktualisieren von Umgebungsvariablen auf Stack-Überlauf

  • Mit der Einstellung im 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 String-Interpolation:

  • Mit der string.Format () Funktion

`

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. Mit Hilfe eine statische Klasse, Dies ist die Lösung, die ich meistens verwenden.

  • Die Implementierung

`

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>

Program.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;
            }
        }
    }
}

Pre-Build-Ereignis:

Projekteinstellungen -> Build Veranstaltungen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top