답변:
당신은 수있는 별도의 구성 파일을 가지고,하지만 당신은이 "수동"를 읽을해야합니다 ConfigurationManager.AppSettings["key"]
어셈블리 실행 만 설정을 읽습니다.
Visual Studio를 IDE로 사용한다고 가정하면 원하는 프로젝트를 마우스 오른쪽 버튼으로 클릭 → 추가 → 새 항목 → 응용 프로그램 구성 파일
App.config
프로젝트 폴더에 추가 되고 <appSettings>
섹션 아래에 설정이 저장됩니다 . Visual Studio를 사용하지 않고 파일을 수동으로 추가하는 경우 파일 이름을 DllName.dll.config로 지정하십시오. 그렇지 않으면 아래 코드가 제대로 작동하지 않습니다.
이제이 파일을 읽으려면 다음과 같은 기능이 있습니다.
string GetAppSetting(Configuration config, string key)
{
KeyValueConfigurationElement element = config.AppSettings.Settings[key];
if (element != null)
{
string value = element.Value;
if (!string.IsNullOrEmpty(value))
return value;
}
return string.Empty;
}
그리고 그것을 사용하려면 :
Configuration config = null;
string exeConfigPath = this.GetType().Assembly.Location;
try
{
config = ConfigurationManager.OpenExeConfiguration(exeConfigPath);
}
catch (Exception ex)
{
//handle errror here.. means DLL has no sattelite configuration file.
}
if (config != null)
{
string myValue = GetAppSetting(config, "myKey");
...
}
ConfigurationManager 클래스를 사용하려면 System.Configuration 네임 스페이스에 대한 참조를 추가해야합니다.
프로젝트를 빌드 할 때 DllName.dll.config
파일 외에도 DLL 뿐만 아니라 DLL 자체로 게시 해야하는 파일입니다.
위의 기본 샘플 코드는 전체 예제에 관심이있는 사용자를위한 다른 답변을 참조하십시오 .
불행히도 실행 파일 당 하나의 app.config 파일 만 가질 수 있으므로 응용 프로그램에 DLL이 연결되어 있으면 자체 app.config 파일을 가질 수 없습니다.
해결책은 다음과 같습니다.
App.config 파일을 클래스 라이브러리 프로젝트에 넣을 필요는 없습니다.
App.config 파일을 클래스 라이브러리의 dll을 참조하는 응용 프로그램에 넣습니다.
예를 들어 app.config 파일을 사용하는 MyClasses.dll이라는 클래스 라이브러리가 있다고 가정 해 보겠습니다.
string connect =
ConfigurationSettings.AppSettings["MyClasses.ConnectionString"];
이제 MyClasses.dll을 참조하는 MyApp.exe라는 Windows 응용 프로그램이 있다고 가정하겠습니다. 여기에는 다음과 같은 항목이있는 App.config가 포함됩니다.
<appSettings>
<add key="MyClasses.ConnectionString"
value="Connection string body goes here" />
</appSettings>
또는
xml 파일은 app.config와 가장 동일합니다. 필요에 따라 xml serialize / deserialize를 사용하십시오. 원하는대로 부를 수 있습니다. 구성이 "정적"이고 변경할 필요가없는 경우 프로젝트에 포함 된 리소스로 추가 할 수도 있습니다.
그것이 약간의 아이디어를 제공하기를 바랍니다.
ConfigurationSettings
이제는 더 이상 사용되지 않고로 대체 ConfigurationManager
되었으므로 이제는 다음과 같습니다.ConfigurationManager.AppSettings
구성 파일은 응용 프로그램 범위이며 어셈블리 범위가 아닙니다. 따라서 라이브러리를 사용하는 모든 응용 프로그램의 구성 파일에 라이브러리의 구성 섹션을 배치해야합니다.
즉, 응용 프로그램의 구성 파일, 특히 appSettings
클래스 라이브러리 의 섹션 에서 구성을 얻는 것은 좋지 않습니다 . 라이브러리에 매개 변수가 필요한 경우 라이브러리를 호출하는 사람이 생성자, 팩토리 메서드 등에서 메서드 인수로 전달해야합니다. 이렇게하면 호출 응용 프로그램이 클래스 라이브러리에서 예상 한 구성 항목을 실수로 재사용하지 못하게됩니다.
즉, XML 구성 파일은 매우 편리하므로 내가 찾은 가장 좋은 방법은 사용자 지정 구성 섹션을 사용하는 것입니다. 라이브러리의 구성을 프레임 워크가 자동으로 읽고 구문 분석하는 XML 파일에 저장하면 잠재적 사고를 피할 수 있습니다.
MSDN의 사용자 지정 구성 섹션에 대해 자세히 알아볼 수 있으며 Phil Haack 에도 유용한 기사 가 있습니다.
appSettings
사용자 정의 섹션이 훌륭한 대안을 제공한다는 것입니다. 결국 ASP.NET 멤버쉽이 사용하는 것은 거의 같습니다.
public class ConfigMan
{
#region Members
string _assemblyLocation;
Configuration _configuration;
#endregion Members
#region Constructors
/// <summary>
/// Loads config file settings for libraries that use assembly.dll.config files
/// </summary>
/// <param name="assemblyLocation">The full path or UNC location of the loaded file that contains the manifest.</param>
public ConfigMan(string assemblyLocation)
{
_assemblyLocation = assemblyLocation;
}
#endregion Constructors
#region Properties
Configuration Configuration
{
get
{
if (_configuration == null)
{
try
{
_configuration = ConfigurationManager.OpenExeConfiguration(_assemblyLocation);
}
catch (Exception exception)
{
}
}
return _configuration;
}
}
#endregion Properties
#region Methods
public string GetAppSetting(string key)
{
string result = string.Empty;
if (Configuration != null)
{
KeyValueConfigurationElement keyValueConfigurationElement = Configuration.AppSettings.Settings[key];
if (keyValueConfigurationElement != null)
{
string value = keyValueConfigurationElement.Value;
if (!string.IsNullOrEmpty(value)) result = value;
}
}
return result;
}
#endregion Methods
}
무언가를하기 위해, 나는 최고의 답변을 수업으로 리팩토링했습니다. 사용법은 다음과 같습니다.
ConfigMan configMan = new ConfigMan(this.GetType().Assembly.Location);
var setting = configMan.GetAppSetting("AppSettingsKey");
현재 소매 소프트웨어 브랜드의 플러그인을 만들고 있는데, 실제로는 .net 클래스 라이브러리입니다. 요구 사항으로 각 플러그인은 구성 파일을 사용하여 구성해야합니다. 약간의 연구와 테스트를 거친 후 다음 클래스를 컴파일했습니다. 완벽하게 작동합니다. 필자의 경우 로컬 예외 처리를 구현하지 않았으므로 더 높은 수준에서 예외를 잡을 수 있습니다.
소수와 두 배의 경우 소수점을 올바르게 조정해야 할 수도 있지만 CultureInfo에서 잘 작동합니다 ...
static class Settings
{
static UriBuilder uri = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase);
static Configuration myDllConfig = ConfigurationManager.OpenExeConfiguration(uri.Path);
static AppSettingsSection AppSettings = (AppSettingsSection)myDllConfig.GetSection("appSettings");
static NumberFormatInfo nfi = new NumberFormatInfo()
{
NumberGroupSeparator = "",
CurrencyDecimalSeparator = "."
};
public static T Setting<T>(string name)
{
return (T)Convert.ChangeType(AppSettings.Settings[name].Value, typeof(T), nfi);
}
}
App.Config 파일 샘플
<add key="Enabled" value="true" />
<add key="ExportPath" value="c:\" />
<add key="Seconds" value="25" />
<add key="Ratio" value="0.14" />
용법:
somebooleanvar = Settings.Setting<bool>("Enabled");
somestringlvar = Settings.Setting<string>("ExportPath");
someintvar = Settings.Setting<int>("Seconds");
somedoublevar = Settings.Setting<double>("Ratio");
Shadow Wizard & MattC의 크레딧
같은 문제에 직면 Parameters
하여 프로젝트에 응용 프로그램 구성 파일을 추가 한 후 정적 클래스를 만들어서 해결했습니다 .
public static class Parameters
{
// For a Web Application
public static string PathConfig { get; private set; } =
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "web.config");
// For a Class Library
public static string PathConfig { get; private set; } =
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", "LibraryName.dll.config");
public static string GetParameter(string paramName)
{
string paramValue = string.Empty;
using (Stream stream = File.OpenRead(PathConfig))
{
XDocument xdoc = XDocument.Load(stream);
XElement element = xdoc.Element("configuration").Element("appSettings").Elements().First(a => a.Attribute("key").Value == paramName);
paramValue = element.Attribute("value").Value;
}
return paramValue;
}
}
그런 다음 다음과 같은 매개 변수를 얻습니다.
Parameters.GetParameter("keyName");
어셈블리에는 자체 app.config 파일이 없습니다. 그것들을 사용하는 응용 프로그램의 app.config 파일을 사용합니다. 따라서 어셈블리가 구성 파일에서 특정 사항을 예상하는 경우 응용 프로그램의 구성 파일에 해당 항목이 있는지 확인하십시오.
여러 응용 프로그램에서 어셈블리를 사용하는 경우 해당 응용 프로그램 각각은 app.config 파일에 해당 항목이 있어야합니다.
내가 권장하는 것은 어셈블리의 클래스에서 속성 값을 정의하는 것입니다.
private string ExternalServicesUrl
{
get
{
string externalServiceUrl = ConfigurationManager.AppSettings["ExternalServicesUrl"];
if (String.IsNullOrEmpty(externalServiceUrl))
throw new MissingConfigFileAppSettings("The Config file is missing the appSettings entry for: ExternalServicesUrl");
return externalServiceUrl;
}
}
여기서 ExternalServicesUrl 속성은 응용 프로그램의 구성 파일에서 값을 가져옵니다. 이 어셈블리를 사용하는 응용 프로그램이 구성 파일에서 해당 설정이 누락되면 예외가 발생합니다. 무언가가 누락되었음을 알 수 있습니다.
MissingConfigFileAppSettings는 사용자 지정 예외입니다. 다른 예외를 던질 수도 있습니다.
물론 더 나은 디자인은 구성 클래스 설정에 의존하기보다는 해당 클래스의 메소드에 해당 값을 매개 변수로 제공하는 것입니다. 이렇게하면 이러한 클래스를 사용하는 응용 프로그램에서 이러한 값을 제공하는 위치와 방법을 결정할 수 있습니다.
서두 : NET 2.0을 사용하고 있습니다.
Yiannis Leoussis 가 게시 한 솔루션 은 받아 들일 만하지 만 문제가 있습니다.
먼저, static AppSettingsSection AppSettings = (AppSettingsSection)myDllConfig.GetSection("appSettings");
null을 반환합니다. 나는 그것을 바꿔야했다.static AppSettingSection = myDllConfig.AppSettings;
그런 다음 return (T)Convert.ChangeType(AppSettings.Settings[name].Value, typeof(T), nfi);
예외를 잡을 수 없습니다. 그래서 나는 그것을 바꿨다.
try
{
return (T)Convert.ChangeType(AppSettings.Settings[name].Value, typeof(T), nfi);
}
catch (Exception ex)
{
return default(T);
}
이것은 잘 작동하지만 다른 dll이 있으면 모든 어셈블리의 코드를 매번 다시 작성해야합니다. 따라서 이것은 필요할 때마다 인스턴스화 할 클래스의 내 버전입니다.
public class Settings
{
private AppSettingsSection _appSettings;
private NumberFormatInfo _nfi;
public Settings(Assembly currentAssembly)
{
UriBuilder uri = new UriBuilder(currentAssembly.CodeBase);
string configPath = Uri.UnescapeDataString(uri.Path);
Configuration myDllConfig = ConfigurationManager.OpenExeConfiguration(configPath);
_appSettings = myDllConfig.AppSettings;
_nfi = new NumberFormatInfo()
{
NumberGroupSeparator = "",
CurrencyDecimalSeparator = "."
};
}
public T Setting<T>(string name)
{
try
{
return (T)Convert.ChangeType(_appSettings.Settings[name].Value, typeof(T), _nfi);
}
catch (Exception ex)
{
return default(T);
}
}
}
구성의 경우 :
<add key="Enabled" value="true" />
<add key="ExportPath" value="c:\" />
<add key="Seconds" value="25" />
<add key="Ratio" value="0.14" />
다음과 같이 사용하십시오.
Settings _setting = new Settings(Assembly.GetExecutingAssembly());
somebooleanvar = _settings.Setting<bool>("Enabled");
somestringlvar = _settings.Setting<string>("ExportPath");
someintvar = _settings.Setting<int>("Seconds");
somedoublevar = _settings.Setting<double>("Ratio");
내가 아는 한 라이브러리 .config에서 원하는 섹션을 응용 프로그램 .config 파일에 복사하여 붙여 넣어야합니다. 실행 가능한 인스턴스 당 하나의 app.config 만 가져옵니다.
사용하지 않는 이유 :
[ProjectNamespace].Properties.Settings.Default.[KeyProperty]
C #My.Settings.[KeyProperty]
VB.NET 용디자인 타임에 다음과 같은 속성을 시각적으로 업데이트하면됩니다.
[Solution Project]->Properties->Settings
구성에서 사용하는 것은 다음과 같이 매우 쉽습니다.
var config = new MiniConfig("setting.conf");
config.AddOrUpdate("port", "1580");
if (config.TryGet("port", out int port)) // if config exist
{
Console.Write(port);
}
자세한 내용은 MiniConfig를 참조하십시오 .
string exeConfigPath = this.GetType().Assembly.Location;
는 다음과 같이 변경해보십시오 :string exeConfigPath = @"C:\MyFolder\DllFolder\ExeName.exe";