Domanda

È possibile fare qualcosa di simile in app.config o web.config i file?

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

Ho bisogno di accedere al Dir2 nel mio codice, semplicemente dicendo:

 ConfigurationManager.AppSettings["Dir2"]

Questo mi aiuterà quando ho installato la mia applicazione in diversi server e le posizioni in cui vorrei solo modificare UNA voce in tutta la mia app.config.(So che posso gestire tutte le concatenazione in codice, ma io lo preferisco così).

È stato utile?

Soluzione

Buona domanda.

Io non credo che ci sia.Credo che sarebbe stato conosciuto abbastanza bene, se c'era un modo facile, e vedo che la Microsoft è la creazione di un meccanismo in Visual Studio 2010 per la distribuzione di diversi file di configurazione per la distribuzione e il test.

Detto questo, tuttavia;Ho scoperto che è in ConnectionStrings la sezione dispone di un tipo di segnaposto chiamato "|DataDirectory|".Forse si potrebbe avere uno sguardo a ciò che è al lavoro ci...

Ecco un pezzo da machine.config mostrando:

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

Altri suggerimenti

Un po ' più complicato, ma molto più flessibile, l'alternativa è creare una classe che rappresenta una sezione di configurazione.Nel app.config / web.config file, si può avere questo:

<?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>

Poi, nel tuo .NET code (io uso C# nel mio esempio), si possono creare due classi di simile a questo:

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

Infine, nel codice di un programma è possibile accedere a app.config variabili, usando le nuove classi, in questo modo:

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

È possibile eseguire utilizzando il mio grande biblioteca: http://nuget.org/List/Packages/Expansive Sorgente è disponibile qui: https://github.com/anderly/Expansive

Ho pensato appena ho visto questa domanda.

In breve, no, non c'è nessuna variabile di interpolazione all'interno di un'applicazione di configurazione.

Hai due opzioni

  1. Si può rotolare il vostro proprio a sostituire le variabili in fase di runtime
  2. Al momento della compilazione, massaggio di configurazione dell'applicazione per la particolare specificità del target ambiente di distribuzione.Alcuni dettagli su questo a trattare con la configurazione incubo

Avete un paio di opzioni.Si potrebbe fare questo con una generazione / distribuzione di passaggio che vorresti processo il file di configurazione sostituendo le variabili con il valore corretto.

Un'altra opzione potrebbe essere quella di definire la propria sezione di Configurazione che ha sostenuto questo.Per esempio, immaginate questo xml:

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

Ora vorrei implementare questo utilizzando la configurazione personalizzata di oggetti di cui vorresti gestire la sostituzione di variabili per voi in fase di runtime.

Di solito, finisco per scrivere una classe statica con proprietà ad accedere a tutte le impostazioni del mio web.config.

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

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

}

Di solito, faccio anche le conversioni di tipo, quando richiesto, in questa classe.Ciò consente di avere un accesso a tipizzazione per la tua config, e se la modifica delle impostazioni, è possibile modificare in un unico luogo.

Di solito, sostituire le impostazioni con questa classe è relativamente semplice e fornisce una maggiore manutenibilità.

È possibile utilizzare le variabili di ambiente nel app.config per tale scenario si descrivono

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

Quindi si può facilmente ottenere il percorso con:

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

All'interno <appSettings> è possibile creare chiavi applicazione,

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

Successivamente si può accedere a questi valori utilizzando:

ConfigurationManager.AppSettings["Keyname"]

Vorrei suggerire che si DslConfig.Con DslConfig è possibile utilizzare gerarchica dei file di configurazione da configurazione Globale, la configurazione per il server host di config per applicazione su ogni host del server (vedere la AppSpike).
Se questo è complicato per voi, si può semplicemente utilizzare la configurazione globale Variabili.var
Basta configurare in Varibales.var

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

E ottenere i valori di configurazione con

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

Io non credo che si possa dichiarare e utilizzare le variabili per definire appSettings chiavi all'interno di un file di configurazione.Ho sempre gestito le concatenazioni in codice come te.

Sto lottando un po ' con quello che vuoi, ma è possibile aggiungere un file di override per l'app impostazioni, quindi avere quel file di override impostata per ogni singolo ambiente.

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

Per stendere i prodotti di cui abbiamo bisogno per configurare un sacco di oggetti con valori simili, usiamo la piccola console di applicazioni che leggono il codice XML e aggiornamento in base ai parametri passati.Questi vengono chiamati dall'installatore dopo aver chiesto all'utente le informazioni richieste.

Vorrei raccomandare a seguito di Matt Hamsmith soluzione.Se è un problema di implementare, quindi perché non creare un metodo di estensione che implementa questo sfondo sul AppSettings classe?

Qualcosa di simile a:

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

    }

All'interno del metodo di ricerca attraverso l'DictionaryInfoConfigSection utilizzo di Linq e restituire il valore con la chiave corrispondente.Devi aggiornare il file di configurazione, però, a qualcosa lungo queste linee:

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

Mi si avvicinò con questa soluzione:

  1. Nelle Impostazioni dell'applicazione.le impostazioni che ho definito una variabile ConfigurationBase (con tipo=stringa Ambito di Applicazione=)
  2. Ho introdotto una variabile in attributi di destinazione nelle Impostazioni.impostazioni, tutte quelle caratteristiche dovevano essere a Portata=Utente
  3. In app.xaml.cs ho letto il valore se il ConfigurationBase
  4. In app.xaml.cs ho sostituito tutte le variabili con il ConfigurationBase valore.Per sostituire i valori in fase di esecuzione gli attributi doveva essere impostato per Scopr=Utente

Io non sono molto contento di questa soluzione, perché devo modificare tutti gli attributi manualmente, se posso aggiungere un nuovo considerare in app.xaml.cs.

Qui un frammento di codice della App.xaml.cs:

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

AGGIORNAMENTO

Appena trovato un miglioramento (di nuovo un frammento di codice della 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);
    }
}

Ora le sostituzioni di lavoro per tutti gli attributi nella mia impostazioni Tipo=stringa e Scope=Utente.Penso che mi piace questo modo.

UPDATE2

A quanto pare impostazione dell'Ambito di Applicazione=non è necessario quando si esegue oltre la proprietà.

Tre Possibili Soluzioni

So di arrivare in ritardo alla festa, ho cercato se c'erano nuove soluzioni per la variabile di configurazione le impostazioni di problema.Ci sono alcune risposte che toccano le soluzioni che ho usato in passato, ma la maggior parte sembra un po ' contorta.Ho pensato di guardare le mie vecchie soluzioni e mettere le implementazioni insieme in modo che potesse aiutare le persone che sono alle prese con lo stesso problema.

Per questo esempio ho usato il seguente app impostazione in un'applicazione console:

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

1.Utilizzare le variabili di ambiente

Credo autocro autocro risposta toccato su di esso.Sto solo facendo un'implementazione che dovrebbe essere sufficiente per la costruzione o il debug senza dover chiudere visual studio.Ho usato questa soluzione back in the day...

  • Creare un evento di pre-generazione che utilizzano il MSBuild variabili

    Avviso:Utilizzare una variabile che non sarà facilmente sostituiti in modo da utilizzare il nome del progetto o qualcosa di simile, come un nome di variabile.

    SETX BaseDir "$(ProjectDir)"

  • Reset variabili;utilizzando qualcosa di simile al seguente:

    Aggiorna le Variabili di Ambiente su Stack Overflow

  • Utilizzare l'impostazione nel tuo codice:

'

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.Utilizzare stringa di interpolazione:

  • Utilizzare la stringa.Funzione 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.Utilizzando una classe statica, Questa è la soluzione che uso principalmente.

  • L'attuazione

`

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

`

  • La classe statica

`

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

`

Codice Progetto:

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>

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

Evento di Pre-generazione:

Progetto Impostazioni -> Build Eventi

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top