문제

다음과 같은 일을 할 수 있습니까? app.config 또는 web.config 파일?

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

그런 다음 간단히 말하면 내 코드에서 Dir2에 액세스하고 싶습니다.

 ConfigurationManager.AppSettings["Dir2"]

이것은 다른 서버와 위치에 응용 프로그램을 설치할 때 도움이 될 것입니다. app.config. (코드의 모든 연결을 관리 할 수는 있지만 이런 식으로 선호합니다).

도움이 되었습니까?

해결책

좋은 질문.

나는 생각하지 않습니다. 쉬운 방법이 있다면 잘 알려져있을 것이라고 생각하며 Microsoft가 배포 및 테스트를 위해 다양한 구성 파일을 배포하기위한 Visual Studio 2010에서 메커니즘을 만들고 있음을 알 수 있습니다.

그러나 그 말로; 나는 당신이 ConnectionStrings 섹션에는 "| datadirectory |"라는 일종의 자리 표시자가 있습니다. 어쩌면 당신은 거기에서 일하고있는 것을 볼 수 있습니다 ...

여기에 조각이 있습니다 machine.config 그것을 보여주기 :

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

다른 팁

약간 더 복잡하지만 훨씬 유연한 대안은 구성 섹션을 나타내는 클래스를 만드는 것입니다. 당신의 app.config / web.config 파일, 당신은 이것을 가질 수 있습니다 :

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

그런 다음 .NET 코드 (내 예에서 C#을 사용하겠습니다)에서 다음과 같은 두 가지 클래스를 만들 수 있습니다.

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

마지막으로 프로그램 코드에서 귀하는 귀하의 app.config 이러한 방식으로 새로운 클래스를 사용하는 변수 :

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

내 광대 한 라이브러리를 사용하여 달성 할 수 있습니다. http://nuget.org/list/packages/expansive소스는 다음과 같습니다. https://github.com/anderly/expansive

방금이 질문을 보았다고 생각했습니다.

요컨대, 애플리케이션 구성 내에 가변 보간이 없습니다.

두 가지 옵션이 있습니다

  1. 런타임에 변수를 대체하기 위해 직접 굴릴 수 있습니다.
  2. 빌드 시점에서 응용 프로그램 구성을 대상 배포 환경의 특정 세부 사항으로 마사지하십시오. 이것에 대한 몇 가지 세부 사항 구성 Nightmare를 다루고 있습니다

몇 가지 옵션이 있습니다. 변수를 올바른 값으로 대체하는 구성 파일을 처리하는 빌드 / 배포 단계 로이 작업을 수행 할 수 있습니다.

또 다른 옵션은이를 지원하는 자체 구성 섹션을 정의하는 것입니다. 예를 들어이 XML을 상상해보십시오.

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

이제 런타임에 변수를 교체하는 것을 처리하는 사용자 정의 구성 객체를 사용 하여이 구현을 구현합니다.

일반적으로 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();
    }

}

일반적 으로이 클래스에서 필요할 때 전환을 입력합니다. 구성에 입력 액세스 할 수 있으며 설정이 변경되면 한 장소에서만 편집 할 수 있습니다.

일반적으로 설정을이 클래스로 바꾸는 것은 비교적 쉽고 훨씬 더 큰 유지 관리 가능성을 제공합니다.

당신은 당신의 환경 변수를 사용할 수 있습니다 app.config 이 시나리오에서 설명합니다

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

그런 다음 다음과 같이 쉽게 경로를 얻을 수 있습니다.

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

내부에 <appSettings> 응용 프로그램 키를 만들 수 있습니다.

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

나중에 다음을 사용 하여이 값에 액세스 할 수 있습니다.

ConfigurationManager.AppSettings["Keyname"]

나는 당신을 제안 할 것입니다 dslconfig. DSLConfig를 사용하면 각 서버 호스트에서 응용 프로그램 당 구성을 위해 서버마다 Config의 계층 구성 파일을 사용할 수 있습니다 (AppSpike 참조).
이것이 당신에게 복잡한 경우, 당신은 글로벌 구성 변수를 사용할 수 있습니다.
Varibales.var로 구성하십시오

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

구성 값을 가져옵니다

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

변수를 선언하고 사용하여 구성 파일 내에서 appSettings 키를 정의 할 수 있다고 생각하지 않습니다. 나는 항상 당신과 같은 코드로 연결을 관리했습니다.

원하는대로 약간 고군분투하고 있지만 앱 설정에 재정의 파일을 추가 한 다음 해당 파일을 환경별로 설정할 수 있습니다.

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

유사한 값으로 많은 항목을 구성 해야하는 제품을 롤아웃하려면 전달 된 매개 변수를 기반으로 XML을 읽고 업데이트하는 소형 콘솔 앱을 사용합니다. 그런 다음 사용자에게 요청한 후 설치 프로그램이 호출합니다. 필수 정보.

Matt Hamsmith의 솔루션을 따르는 것이 좋습니다. 구현해야 할 문제라면 AppSettings 클래스의 백그라운드에서이를 구현하는 확장 방법을 작성하지 않겠습니까?

같은 것 :

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

    }

방법 내에서 LINQ를 사용하여 DictionaryInfoconfigsection을 통해 검색하고 일치 키로 값을 반환합니다. 그래도 구성 파일을 다음과 같은 줄을 따라 업데이트해야합니다.

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

이 솔루션을 생각해 냈습니다.

  1. 애플리케이션 설정에서 세트 I는 변수 구성베이스를 정의했습니다 (type = string scope = application)
  2. 설정에서 대상 속성에 변수를 소개했습니다. 세트팅, 모든 속성을 SCOPE = USER로 설정해야했습니다.
  3. app.xaml.cs에서 configurationbase이면 값을 읽습니다.
  4. app.xaml.cs에서 모든 변수를 configurationbase 값으로 대체했습니다. 런 타임시 값을 바꾸려면 속성을 scop = user로 설정해야했습니다.

모든 속성을 수동으로 변경해야하기 때문에이 솔루션에 정말 만족하지 않습니다. 새 속성을 추가하면 app.xaml.cs에서 고려해야합니다.

여기에서 app.xaml.cs의 코드 스 니펫 :

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

업데이트

방금 개선 사항을 찾았습니다 (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);
    }
}

이제 대체품은 내 설정의 모든 속성에 대해 type = string 및 scope = user가 있습니다. 나는 이런 식으로 그것을 좋아한다고 생각한다.

업데이트 2

분명히 SCOPE = APPLATION을 속성을 실행할 때 응용 프로그램이 필요하지 않습니다.

세 가지 가능한 솔루션

나는 파티에 늦게 온다는 것을 알고 있습니다. 가변 구성 설정 문제에 대한 새로운 솔루션이 있는지보고 있습니다. 과거에 사용한 솔루션을 만지는 몇 가지 답변이 있지만 대부분은 약간 복잡해 보입니다. 나는 기존 솔루션을보고 구현을 정리하여 같은 문제로 어려움을 겪고있는 사람들을 도울 수 있다고 생각했습니다.

이 예에서는 콘솔 애플리케이션에서 다음 앱 설정을 사용했습니다.

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

1. 환경 변수를 사용합니다

나는 Autocro를 믿는다 Autocro의 답변 그것에 만졌습니다. 비주얼 스튜디오를 닫지 않고 구축하거나 디버깅 할 때 충분 해야하는 구현을하고 있습니다. 나는이 솔루션을 하루에 다시 사용했습니다 ...

  • MSBuild 변수를 사용할 수있는 사전 건축 이벤트 작성

    경고 : 쉽게 교체되지 않는 변수를 사용하므로 프로젝트 이름이나 변수 이름과 유사한 것을 사용하십시오.

    SETX BaseDir "$(ProjectDir)"

  • 변수 재설정; 다음과 같은 것을 사용합니다.

    스택 오버플로에서 환경 변수를 새로 고치십시오

  • 코드의 설정을 사용하십시오.

'

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. 문자열 보간 사용 :

  • 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. 정적 클래스를 사용하여 이것은 내가 주로 사용하는 솔루션입니다.

  • 구현

`

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

`

프로젝트 코드 :

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

사전 제작 이벤트 :

프로젝트 설정 -> 이벤트 빌드

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top