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;"
이 질문을 방금 본 것 같습니다.
요컨대, 애플리케이션 구성 내에 변수 보간이 없습니다.
두 가지 옵션이 있습니다
- 런타임에 변수를 대체하기 위해 직접 굴릴 수 있습니다.
- 빌드시 대상 배치 환경의 특정 특성에 맞게 애플리케이션 구성을 마사지하십시오. 구성 악몽 을 처리 할 때 이에 대한 몇 가지 세부 사항
몇 가지 옵션이 있습니다. 변수를 올바른 값으로 바꾸는 구성 파일을 처리하는 빌드 / 배포 단계로이를 수행 할 수 있습니다.
또 다른 옵션은이를 지원하는 자체 구성 섹션을 정의하는 것입니다. 예를 들어 다음 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>
이 솔루션을 생각해 냈습니다.
- 응용 프로그램 Settings.settings에서 변수 ConfigurationBase를 정의했습니다 (type = string Scope = Application 포함).
- Settings.settings의 대상 속성에 변수를 도입했습니다. 모든 속성은 Scope = User로 설정해야합니다.
- app.xaml.cs에서 ConfigurationBase가
- 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
'Programing' 카테고리의 다른 글
Android에서 AES 암호화를 사용하는 모범 사례는 무엇입니까? (0) | 2020.09.19 |
---|---|
이 유효하지 않은 코드가 g ++ 6.0에서 성공적으로 컴파일되는 이유는 무엇입니까? (0) | 2020.09.19 |
C ++에 대한 Maven과 같은 종속성 관리? (0) | 2020.09.19 |
MongoDB의 다중 테넌트 데이터베이스에 대해 권장되는 접근 방식은 무엇입니까? (0) | 2020.09.19 |
스칼라에서 앱 특성과 주요 방법 사용의 차이점 (0) | 2020.09.19 |