Programing

app.config / web.config 내의 변수

lottogame 2020. 9. 19. 11:53
반응형

app.config / web.config 내의 변수


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"]

이렇게하면 전체 .NET에서 하나의 항목 만 변경하면되는 다른 서버와 위치에 응용 프로그램을 설치할 때 도움이됩니다 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"

내 라이브러리 Expansive를 사용하여 수행 할 수 있습니다 . 여기 에서 nuget에서도 사용할 수 있습니다 .

이를 기본 사용 사례로 설계했습니다.

보통의 예 (AppSettings를 토큰 확장의 기본 소스로 사용)

app.config에서 :

<configuration>
    <appSettings>
        <add key="Domain" value="mycompany.com"/>
        <add key="ServerName" value="db01.{Domain}"/>
    </appSettings>
    <connectionStrings>
        <add name="Default" connectionString="server={ServerName};uid=uid;pwd=pwd;Initial Catalog=master;" provider="System.Data.SqlClient" />
    </connectionStrings>
</configuration>

확장 할 문자열에 .Expand () 확장 메서드를 사용합니다 .

var connectionString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
connectionString.Expand() // returns "server=db01.mycompany.com;uid=uid;pwd=pwd;Initial Catalog=master;"

또는

다음과 같이 Dynamic ConfigurationManager 래퍼 "Config"를 사용합니다 (Expand ()에 대한 명시 적 호출이 필요하지 않음).

var serverName = Config.AppSettings.ServerName;
// returns "db01.mycompany.com"

var connectionString = Config.ConnectionStrings.Default;
// returns "server=db01.mycompany.com;uid=uid;pwd=pwd;Initial Catalog=master;"

고급 예제 1 (토큰 확장을위한 기본 소스로 AppSettings 사용)

app.config에서 :

<configuration>
    <appSettings>
        <add key="Environment" value="dev"/>
        <add key="Domain" value="mycompany.com"/>
        <add key="UserId" value="uid"/>
        <add key="Password" value="pwd"/>
        <add key="ServerName" value="db01-{Environment}.{Domain}"/>
        <add key="ReportPath" value="\\{ServerName}\SomeFileShare"/>
    </appSettings>
    <connectionStrings>
        <add name="Default" connectionString="server={ServerName};uid={UserId};pwd={Password};Initial Catalog=master;" provider="System.Data.SqlClient" />
    </connectionStrings>
</configuration>

확장 할 문자열에 .Expand () 확장 메서드를 사용합니다.

var connectionString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
connectionString.Expand() // returns "server=db01-dev.mycompany.com;uid=uid;pwd=pwd;Initial Catalog=master;"

이 질문을 방금 본 것 같습니다.

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

두 가지 옵션이 있습니다

  1. 런타임에 변수를 대체하기 위해 직접 굴릴 수 있습니다.
  2. 빌드시 대상 배치 환경의 특정 특성에 맞게 애플리케이션 구성을 마사지하십시오. 구성 악몽처리 할 때 이에 대한 몇 가지 세부 사항

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

또 다른 옵션은이를 지원하는 자체 구성 섹션을 정의하는 것입니다. 예를 들어 다음 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();
    }

}

일반적으로이 클래스에서 필요할 때 유형 변환도 수행합니다. 구성에 대한 입력 된 액세스 권한을 가질 수 있으며 설정이 변경되면 한 곳에서만 편집 할 수 있습니다.

일반적으로 설정을이 클래스로 바꾸는 것은 비교적 쉽고 유지 관리가 훨씬 쉽습니다.


내부에서 <appSettings>애플리케이션 키를 만들 수 있습니다.

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

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

ConfigurationManager.AppSettings["Keyname"]

app.config설명하는 시나리오에 대해 환경 변수를 사용할 수 있습니다.

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

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

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

DslConfig를 제안합니다 . DslConfig를 사용하면 전역 구성, 서버 호스트 별 구성에서 각 서버 호스트의 애플리케이션 별 구성까지 계층 적 구성 파일을 사용할 수 있습니다 (AppSpike 참조).
이것이 복잡하다면 전역 구성 Variables.var를 사용할 수
있습니다. 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. 응용 프로그램 Settings.settings에서 변수 ConfigurationBase를 정의했습니다 (type = string Scope = Application 포함).
  2. Settings.settings의 대상 속성에 변수를 도입했습니다. 모든 속성은 Scope = User로 설정해야합니다.
  3. app.xaml.cs에서 ConfigurationBase가
  4. app.xaml.cs에서 모든 변수를 ConfigurationBase 값으로 대체했습니다. 런타임에 값을 바꾸려면 속성을 Scopr = 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 = Application을 설정할 필요가 없습니다.


세 가지 가능한 솔루션

나는 내가 파티에 늦게 오는 것을 알고 있으며, 변수 구성 설정 문제에 대한 새로운 해결책이 있는지 찾고있었습니다. 내가 과거에 사용한 솔루션과 관련된 몇 가지 답변이 있지만 대부분은 약간 복잡해 보입니다. 같은 문제로 어려움을 겪는 사람들에게 도움이 될 수 있도록 이전 솔루션을 살펴보고 구현을 통합 할 것이라고 생각했습니다.

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

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

1. 환경 변수 사용

나는 autocro autocro의 대답이 그것에 닿았 다고 생각 합니다. Visual Studio를 닫지 않고 빌드하거나 디버깅 할 때 충분한 구현을 수행하고 있습니다. 저는이 솔루션을 예전에 사용했습니다 ...

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

빌드 전 이벤트 :

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

참고URL : https://stackoverflow.com/questions/603009/variables-within-app-config-web-config

반응형