라이브러리 (DLL)의 'app.config'와 동일


149

에 해당하는 있습니까 app.config라이브러리 (DLL)에 대한이? 그렇지 않은 경우 라이브러리와 관련된 구성 설정을 저장하는 가장 쉬운 방법은 무엇입니까? 라이브러리는 다른 응용 프로그램에서 사용될 수 있습니다.

답변:


161

당신은 수있는 별도의 구성 파일을 가지고,하지만 당신은이 "수동"를 읽을해야합니다 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 자체로 게시 해야하는 파일입니다.

위의 기본 샘플 코드는 전체 예제에 관심이있는 사용자를위한 다른 답변을 참조하십시오 .


1
@Rodney string exeConfigPath = this.GetType().Assembly.Location;는 다음과 같이 변경해보십시오 :string exeConfigPath = @"C:\MyFolder\DllFolder\ExeName.exe";
Shadow Wizard is Ear For You

1
dll이 resharper 단위 테스트 도구로 알 수없는 폴더에 복사되는 경우이 작업을 수행하는 방법을 알고 있습니까?
Autodidact

11
응용 프로그램을 참조하여 DllName.dll.config 생성을 자동화하기 위해 app.config의 이름을 DllName.dll.config로 바꾸고 "Copy to Output Directory"속성을 "Copy always"로 변경했습니다. . 또한 config.ConnectionStrings.ConnectionStrings [connStringName] .ConnectionString을 사용하여 검색 할 수있는 연결 문자열이 필요했습니다.
Jeff G

2
app.cfg 파일 이름은 appcfg 값을 읽는 데 매우 중요합니다. 파일 이름은 "DLL_NAME.DLL.CONFIG"
SaddamBinSyed

2
마지막 코멘트 수정. VS2017 솔루션에서는 테스트 및 DLL 프로젝트에서 작동하지 않는 새로운 App.config 파일을 제거하고 테스트 프로젝트에 다시 추가하여 갑자기 작동하기 시작했습니다! 내 App.config 설정이 DLL.configs에 자동으로 포함됩니다. 어떤 구호!
Zeek2

30

불행히도 실행 파일 당 하나의 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를 사용하십시오. 원하는대로 부를 수 있습니다. 구성이 "정적"이고 변경할 필요가없는 경우 프로젝트에 포함 된 리소스로 추가 할 수도 있습니다.

그것이 약간의 아이디어를 제공하기를 바랍니다.


6
ConfigurationSettings이제는 더 이상 사용되지 않고로 대체 ConfigurationManager되었으므로 이제는 다음과 같습니다.ConfigurationManager.AppSettings
Gone Coding

2
다운 투표. 질문은 응용 프로그램이 아닌 dll별로입니다. 최상의 솔루션 : stackoverflow.com/a/5191101/2935383
raiserle

3
늦게 묶인 dll의 경우이 제안이 작동하지 않아 의심 할 여지가 있다고 생각합니다.
beanmf

9

구성 파일은 응용 프로그램 범위이며 어셈블리 범위가 아닙니다. 따라서 라이브러리를 사용하는 모든 응용 프로그램의 구성 파일에 라이브러리의 구성 섹션을 배치해야합니다.

즉, 응용 프로그램의 구성 파일, 특히 appSettings클래스 라이브러리 의 섹션 에서 구성을 얻는 것은 좋지 않습니다 . 라이브러리에 매개 변수가 필요한 경우 라이브러리를 호출하는 사람이 생성자, 팩토리 메서드 등에서 메서드 인수로 전달해야합니다. 이렇게하면 호출 응용 프로그램이 클래스 라이브러리에서 예상 한 구성 항목을 실수로 재사용하지 못하게됩니다.

즉, XML 구성 파일은 매우 편리하므로 내가 찾은 가장 좋은 방법은 사용자 지정 구성 섹션을 사용하는 것입니다. 라이브러리의 구성을 프레임 워크가 자동으로 읽고 구문 분석하는 XML 파일에 저장하면 잠재적 사고를 피할 수 있습니다.

MSDN의 사용자 지정 구성 섹션에 대해 자세히 알아볼 수 있으며 Phil Haack 에도 유용한 기사 가 있습니다.


7
"클래스 라이브러리의 구성 파일에서 구성을 얻는 것은 좋지 않습니다."-나는 이것에 크게 동의하지 않습니다. 예를 들어, DAL 클래스 라이브러리는 일반적으로이 정보를 BLL 티어에서 전달하지 않고 애플리케이션 구성 파일에서 연결 문자열과 같은 구성 데이터를 가져와야합니다. 구성 (예 : ASP.NET 멤버쉽)을 사용하는 모든 프레임 워크 클래스는이 방식으로 작동합니다.
Joe

나는 대답을 약간 수정했다. 나는 여전히 내가 말한 것을 지키고 있지만, 그렇습니다. 구성 파일을 전혀 사용해서는 안된다는 것을 결코 암시하지 않습니다. 내가 의미하는 바는 컨벤션 기반 대신 appSettings사용자 정의 섹션이 훌륭한 대안을 제공한다는 것입니다. 결국 ASP.NET 멤버쉽이 사용하는 것은 거의 같습니다.
madd0

5
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");

4

Visual Studio에서 클래스 라이브러리 프로젝트에 설정을 추가하면 (프로젝트 속성, 설정), 관련 userSettings / applicatioNSettings 섹션과 설정에서 이러한 설정의 기본값을 사용하여 app.config 파일을 프로젝트에 추가합니다. 파일.

그러나이 구성 파일은 런타임에 사용되지 않으며 대신 클래스 라이브러리가 호스팅 응용 프로그램의 구성 파일을 사용합니다.

이 파일을 생성하는 주된 이유는 설정을 호스트 응용 프로그램의 구성 파일에 복사 / 붙여 넣을 수 있기 때문입니다.


4

현재 소매 소프트웨어 브랜드의 플러그인을 만들고 있는데, 실제로는 .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의 크레딧


1
이것이 정답입니다. 매우 콤팩트하며 "바로 사용할 수 있습니다". 좋은 물건
nmarler

2

원래 질문에 대한 응답으로, 나는 일반적으로 테스트 프로젝트에 구성 파일을 링크로 추가합니다. 그런 다음 DeploymentItem 속성을 사용하여 테스트 실행의 Out 폴더에 추가 할 수 있습니다.

[TestClass]
[DeploymentItem("MyProject.Cache.dll.config")]
public class CacheTest
{
    .
    .
    .
    .
}

어셈블리는 프로젝트에 따라 다를 수 없다는 의견에 응답 할 수 있으며 유연성이 뛰어납니다. IOC 프레임 워크로 작업 할 때


2

같은 문제에 직면 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");

1
훌륭한! 이를 통해 대상 컴퓨터에서 Windows Application Driver 자동 테스트를 실행할 수있었습니다. 필자의 경우 dll은 테스트 프로젝트에서 가져온 것입니다. 내가 추가 할 유일한 것은 Win App Driver (및 다른 형태의 자동 테스트)에서 BaseDirectory는 실제로 매번 변경되는 출력 폴더라는 것입니다. AppDomain.CurrentDomain.BaseDirectory.Substring (0, AppDomain.CurrentDomain.BaseDirectory.IndexOf ( "TestResults"))과 같은 부분 문자열을 사용해야했습니다. 이 방법으로 구성 파일이 테스트 dll과 같은 폴더에 있기 때문에 원하지 않는 출력 폴더를 잘라낼 수 있습니다.
Ewan

1

어셈블리에는 자체 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 어셈블리 DLL에서 xUnit 테스트를 실행할 때 xUnit은 런타임에 라이브러리의 .config를 읽습니다. 그리고 테스트 또는 DLL 프로젝트에 추가 된 App.config는 무시합니다.
Zeek2

1

기존 항목 추가를 사용하여 dll 프로젝트에서 앱 구성을 선택하십시오. 추가를 클릭하기 전에 추가 버튼의 오른쪽에있는 작은 아래쪽 화살표를 사용하여 "링크로 추가"

나는 항상 내 dev 에서이 작업을 수행합니다.


1

서두 : 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");

삭제 투표를 검토하십시오. 내 실수는 답을 쓰면서 답을 보냈다.
Matteo Gaggiano

0

내가 아는 한 라이브러리 .config에서 원하는 섹션을 응용 프로그램 .config 파일에 복사하여 붙여 넣어야합니다. 실행 가능한 인스턴스 당 하나의 app.config 만 가져옵니다.


사용자 정의 구성 섹션을 사용하는 경우 configSource 속성을 사용할 수 있습니다 : <MySection configSource = "mysection.config"/> 및 구성 파일은 dll로만 복사
Jan Remunda

예를 들어 항상 빈 문자열과 메일 서버 설정을 반환하는 함수에 대한 새로운 질문을 추가했습니다.> stackoverflow.com/questions/25123544/… 및> stackoverflow.com/questions/25138788/… 그래서 누군가가 내가 그들에게 답장하기를 바랍니다. DLL에 값을 하드 코딩하는 것의 가장자리에 거의 있습니다!
MonkeyMagix

0

사용하지 않는 이유 :

  • [ProjectNamespace].Properties.Settings.Default.[KeyProperty] C #
  • My.Settings.[KeyProperty] VB.NET 용

디자인 타임에 다음과 같은 속성을 시각적으로 업데이트하면됩니다.

[Solution Project]->Properties->Settings


dll에 대한 설정 파일이 자동으로 생성됩니다. 그러나 런타임시 구성 파일에서 수정 된 값을 읽을 수 없습니다. 마지막으로 호출 응용 프로그램의 값을 보여줍니다. @Joe answer
Code Pope

사용자 구성으로 구성된 경우 아니오 아이디어는 사용자가 원하는 것을 편집하고 런타임에 구성한 다음 저장하는 것입니다. 그런 다음 사용자가 라이브러리로 작업 할 때 구성이로드되고 해당 사용자 경로에 저장되지만 그에게만 적용됩니다.
Pedro Mora

0

구성에서 사용하는 것은 다음과 같이 매우 쉽습니다.

var config = new MiniConfig("setting.conf");

config.AddOrUpdate("port", "1580");

if (config.TryGet("port", out int port)) // if config exist
{
    Console.Write(port);
}

자세한 내용은 MiniConfig를 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.