클래스 라이브러리 용 app.config


83

VS2008 마법사에서 클래스 라이브러리에 대해 생성 된 app.config 파일을 볼 수 없습니다. 내 연구에서 응용 프로그램에는 app.config가 하나만 존재한다는 것을 발견했습니다.

app.config를 클래스 라이브러리에 수동으로 추가하는 것이 나쁜 일입니까? 아니면 클래스 라이브러리에서 app.config의 목적을 제공하는 다른 메서드가 있습니까?

app.config 파일에 log4net 구성 정보를 저장해야합니다.


3
라이브러리에서 실행 가능한 프로젝트 구성 파일을 읽을 수 있습니다.
Akram Shahda 2011

답변:


102

일반적으로 클래스 라이브러리 프로젝트에 파일을 추가 해서는 안됩니다app.config . 고통스러운 구부리거나 뒤틀림 없이는 사용되지 않습니다. 그것은 도서관 프로젝트를 전혀 해치지 않습니다. 단지 아무것도하지 않을 것입니다.

대신 라이브러리를 사용하는 응용 프로그램을 구성합니다. 따라서 필요한 구성 정보가 여기로 이동합니다. 라이브러리를 사용할 수있는 각 응용 프로그램에는 다른 요구 사항이있을 수 있으므로 실제로 논리적으로도 의미가 있습니다.


23
잘 됐네요. 그래도 나는 당신의 질문에 대답하지 않았습니다. 여기에서 질문하는 사람에게는 적용되지 않는 일종의 자체 개발 구성 시스템이 있습니다.
Andrew Barber

1
모든 테스트 케이스에 대해 NUnit에서 실행하는 Selenium WebDriver 클래스 라이브러리가 있습니다. NUnit에서 구성 설정에 대해 걱정할 필요가 없습니다. 이 작업을 수행하려면 어떻게 구부리고 비틀 수 있습니까? :-)
MacGyver

3
알아 냈습니다 ... NUnit을 사용하는 경우 * .nunit 프로젝트 파일 이름과 동일한 이름으로 app.config 파일의 이름을 지정합니다. 예를 들어 프로젝트 이름을 "ClassLibraryA.nunit"으로 지정한 경우 클래스 라이브러리 구성 파일의 이름을 "ClassLibraryA.config"로 지정합니다. 또한 동일한 폴더 / 디렉토리에 있어야합니다. NUnit은 실제로 이것을 기본 구성 파일로 사용하고 있습니다. .... System.Configuration (.NET 탭에서)에 대한 참조를 추가하고 .... 다음 코드를 사용합니다. string settingValue = ConfigurationManager.AppSettings [ "settingName"];
MacGyver 2012

2
통합 테스트를 할 때 설정을 어떻게 권장합니까? 나에게는 연결 문자열이있는 해당 테스트 라이브러리에 app.config가있는 것이 논리적으로 보입니다.
Tomas Jansson 2013

2
자신이 소유하지 않아 애플리케이션을 구성 할 수없는 경우 어떻게해야합니까?
전압 스파이크

50

이 답변이 아직 제공되지 않은 이유를 모르겠습니다.

동일한 라이브러리의 다른 호출자는 일반적으로 다른 구성을 사용합니다. 이는 구성 이 클래스 라이브러리가 아닌 실행 가능한 응용 프로그램 에 있어야 함을 의미합니다 .

클래스 라이브러리 프로젝트 내에서 app.config를 만들 수 있습니다. 라이브러리 내에서 생성 한 항목에 대한 기본 구성이 포함됩니다. 예를 들어 클래스 라이브러리 내에서 Entity Framework 모델을 만드는 경우 연결 문자열이 포함됩니다.

그러나 이러한 설정은 라이브러리를 호출하는 실행 가능한 응용 프로그램에서 사용되지 않습니다. 대신 이러한 설정을 library.dll.config 파일에서 호출자의 app.config 또는 web.config로 복사하여 호출자 및 호출자가있는 환경에 맞게 변경할 수 있습니다. 배포.

이것이 1 일차부터 .NET과 함께해온 방식입니다.


2
하지만 클래스 라이브러리에서 webserice 기능을 호출해야하는 경우 어떻게해야합니까? VS가 기본 app.config를 만들었지 만 웹 서비스 함수를 호출하려고 할 때 내 응용 프로그램이 충돌했습니다. 구성 항목을 찾을 수 없습니다 ...
Laserson

클래스 라이브러리 app.config에 배치 된 요소를 클래스 라이브러리 호출자의 app.config 또는 web.config에 복사해야합니다. 이렇게하면 호출자가 구성을 제어 할 수 있습니다. 예를 들어 호출자는 이제 클래스 라이브러리가 호출하는 서비스의 URL을 변경할 수 있으며 클래스 라이브러리는 변경 사항에 대해서도 알지 못합니다.
John Saunders

6
@John Saunders : "필요할 수 있음"은 정확히 올바른 단어입니다. 따라서 구성 설정이 서버 (예 : 연결 문자열)별로 만 다른 상황이있을 수 있으며 dll을 사용하는 모든 어셈블리에 대해 여러 번 복사하는 것보다 dll이 고유 한 구성을 갖도록하는 것이 더 편리합니다. 제 생각에는 Microsoft / .NET 선호하는 사용은 성배가 아닙니다. 실제로 배포 시나리오에서 가장 편리한 것이 무엇인지에 따라 다릅니다. Todd에게 말할 필요가 없습니다. 그의 의견은 귀 하나 Microsoft만큼 중요합니다.

이 솔루션에 정말 관심이 있습니다. 이상적으로 들립니다. 라이브러리는 기본 설정을 전달하는 반면 응용 프로그램은이를 재정의 할 수 있습니다. 라이브러리의 app.config에서 실행중인 어셈블리의 app.config로 설정을 전파하는 방법을 확장하거나 관련 리소스로 연결 하시겠습니까?
분쇄

@crush : "복사 및 붙여 넣기"라고합니다. .NET의 강력한 형식 설정 기능은 어셈블리에 기본값을 적용하므로 약간의 도움이 될 수 있습니다.
John Saunders

43

Jon, 귀하의 질문에 올바르게 대답하지 않은 많은 의견이 제공되었습니다.

내 의견을 제시하고 요청한 것을 정확히 수행하는 방법을 알려 드리겠습니다.

어셈블리에 자체 구성 파일이 없을 이유가 없습니다. 원자 성의 첫 번째 수준 (진짜 단어입니까?)이 응용 프로그램 수준에있는 이유는 무엇입니까? 솔루션 수준이 아닌 이유는 무엇입니까? 그것은 임의적이고 최선의 결정이며 따라서 의견입니다. 로깅 라이브러리를 작성하고 이에 대한 구성 파일을 포함하려는 경우 전역 적으로 사용되는 경우 내장 설정 기능에 연결할 수없는 이유는 무엇입니까? 우리는 모두 해냈습니다. 다른 개발자에게 "강력한"기능을 제공하려고 노력했습니다. 어떻게? 본질적으로 제한으로 해석 된 가정을합니다. 이것이 바로 MS가 설정 프레임 워크로 수행 한 작업이므로 약간 "만약"해야합니다.

질문에 직접 답하려면 구성 파일 (xml)을 수동으로 추가하고 라이브러리와 일치하고 "config"확장자를 포함하도록 이름을 지정하십시오. 예:

MyDomain.Mylibrary.dll.Config

다음으로 ConfigurationManager를 사용하여 파일을로드하고 설정에 액세스합니다.

string assemblyPath = new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath;
Configuration cfg = ConfigurationManager.OpenExeConfiguration(assemblyPath);
string result = cfg.AppSettings.Settings["TEST_SETTING"].Value;

앱 구성 파일을 명시 적으로 선택 했더라도 이것은 machine.config 계층 구조를 완전히 지원합니다. 즉, 설정이 없으면 더 높게 해결됩니다. 설정은 machine.config 항목도 무시합니다.


3
-1 : 귀하의 의견 자체는 중요하지 않습니다. 사실이 중요합니다. 1 일차부터 .NET은 라이브러리 호출자가 라이브러리 내의 항목 구성을 결정하도록 만들어졌습니다. 라이브러리의 다른 호출자가 다른 구성을 필요로 할 수 있으므로 구성에 대해 실제로 의미가있는 유일한 것입니다.
John Saunders

19
@JohnSaunders "라이브러리의 다른 호출자는 다른 구성이 필요할 수 있습니다." 정확히는 다른 구성이 "필요할 수 있습니다". 구성이 호출자에 따라 달라지는 모든 경우에 논리가 완벽합니다. 그러나 구성이 클래스 라이브러리에 대해 내부적으로 사용되는 몇 가지 경우가 있으며 호출자가 무엇이든 구성이 정확히 동일합니다. 라이브러리를 사용하는 10 개의 애플리케이션이있는 경우 정확히 동일한 구성을 복사하여 10 개의 구성 파일에 붙여 넣는 것이 더 나쁩니다.
wired_in 2014 년

3
@ToddBeaulieu : 당신이 원하는 단어는 '원 자성'이라고 생각합니다.
nicodemus13 2012

3
플러그인 아키텍처에서 모든 플러그인에 자체 구성 파일이 있으면 실제로 의미가 있습니다.
Davatar

4
@RMuesi 아무도 그것이 결코 변하지 않는다고 말했고, 단지 그것이 도서관의 호출자에 의존하지 않는다고 말했습니다. 구성은 라이브러리를 디버깅하는지 프로덕션 릴리스를 디버깅하는지에 따라 변경 될 수 있습니다. 환경 등에 따라 달라질 수 있습니다.
wired_in

6

실제로 구현중인 클래스 라이브러리는이를 사용 하는 애플리케이션 내부의 app.config 에서 정보를 검색 하므로 VS의 .net에서 클래스 라이브러리에 대한 구성을 구현하는 가장 올바른 방법은 다음에서 app.config 를 준비 하는 것입니다. 라이브러리 구성과 같이 소비하는 모든 것을 구성하는 응용 프로그램입니다.

나는 log4net으로 약간 작업했으며 응용 프로그램을 준비한 사람은 항상 main app.config 내에 log4net 구성 섹션이 있음을 발견했습니다 .

이 정보가 도움이 되셨기를 바랍니다.

만나서 찾은 솔루션에 대한 의견을 게시하십시오.

편집하다:

다음 링크에는 app.config가 있습니다. log4net 섹션 가 있습니다.

http://weblogs.asp.net/tgraham/archive/2007/03/15/a-realistic-log4net-config.aspx


2
+1 정확합니다. 은 app.config결국은 ... 실행이 아닌 개별 클래스 라이브러리 것으로 실제 프로그램에서로드됩니다. 솔직히 얼마나 많은 사람들이이 기본적인 사실을 모르고 있는지 약간 혼란 스럽습니다.
Andrew Barber

아마도 사람들은 Java 언어에서 왔고 거기에 log4java.properties와 응용 프로그램에 대한 별도의 속성 파일이 있습니다.
Amedio 2011

6

클래스 라이브러리를 사용하는 동안 log4Net을 사용하여 프로젝트 로깅을 구성하려는 경우 실제로 구성 파일이 필요하지 않습니다. 클래스에서 log4net 로거를 구성하고 해당 클래스를 라이브러리로 사용할 수 있습니다.

log4net은이를 구성하는 모든 옵션을 제공합니다.

아래 코드를 찾으십시오.

public static void SetLogger(string pathName, string pattern)
        {
            Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();

            PatternLayout patternLayout = new PatternLayout();
            patternLayout.ConversionPattern = pattern;
            patternLayout.ActivateOptions();

            RollingFileAppender roller = new RollingFileAppender();
            roller.AppendToFile = false;
            roller.File = pathName;
            roller.Layout = patternLayout;
            roller.MaxSizeRollBackups = 5;
            roller.MaximumFileSize = "1GB";
            roller.RollingStyle = RollingFileAppender.RollingMode.Size;
            roller.StaticLogFileName = true;
            roller.ActivateOptions();
            hierarchy.Root.AddAppender(roller);

            MemoryAppender memory = new MemoryAppender();
            memory.ActivateOptions();
            hierarchy.Root.AddAppender(memory);

            hierarchy.Root.Level = log4net.Core.Level.Info;
            hierarchy.Configured = true;
      }

이제 XmlConfigurator.Configure (new FileInfo ( "app.config"))를 호출하는 대신 원하는 경로와 패턴으로 SetLogger를 직접 호출하여 Global.asax 응용 프로그램 시작 기능에서 로거를 설정할 수 있습니다.

그리고 아래 코드를 사용하여 오류를 기록하십시오.

        public static void getLog(string className, string message)
        {
            log4net.ILog iLOG = LogManager.GetLogger(className);
            iLOG.Error(message);    // Info, Fatal, Warn, Debug
        }

다음 코드를 사용하면 web.config 응용 프로그램이나 라이브러리의 app.config 내부에 한 줄을 쓸 필요가 없습니다.


2
나는이 대답이 Log4net 사용하는 OP의 질문에 대답 ...이 오히려 구성 파일이 라이브러리에 대한 허용 여부를 논의보다 ... 가장 좋은 대답은 느낌
saurav을

1
질문에서 log4net을 예로 사용했지만 실제 질문은 일반적으로 구성에 관한 것입니다. log4net에 대한 답변은 실제로 관련이 없다고 말하고 싶습니다.
binki

4

실제로 드물게 클래스 라이브러리에 app.config를 저장하고 (수동으로 추가하여) OpenExeConfiguration으로 구문 분석 할 수 있습니다.

 var fileMap =
    new ExeConfigurationFileMap {ExeConfigFilename = 
    @"C:\..somePath..\someName.config"};
 System.Configuration.Configuration config =
    ConfigurationManager.OpenMappedExeConfiguration(fileMap, 
    ConfigurationUserLevel.None);

이것의 실제 필요성을 정말로 추정해야합니다. 추상 데이터의 경우 최상의 솔루션은 아니지만 "구성 섹션"이 매우 유용 할 수 있습니다 !!

예를 들어, 채널 팩토리 T를 기반으로 Unity Container 및 Injection Factory를 사용하여 메타 데이터없이 분리 된 N-Tier WCF 아키텍처를 구성했습니다. [서비스 계약] 인터페이스와 공통 app.config 만있는 externall ClassLibrary dll을 순서대로 추가했습니다. 클라이언트 섹션에서 엔드 포인트를 읽고 한곳에서 쉽게 추가 / 변경할 수 있습니다.


3

당신은 추가 하시겠습니까 의 App.config를 당신에게 테스트 당신이 추적 / 로거를 사용하는 경우, 클래스 라이브러리. 그렇지 않으면 TestDriven.Net과 같은 테스트 실행기를 통해 테스트를 실행할 때 아무것도 기록되지 않습니다 .

예를 들어 TraceSource프로그램에서 사용하지만 추적 / 로그 구성이 있는 App.config 파일을 테스트 클래스 라이브러리에 추가하지 않는 한 테스트를 실행해도 아무것도 기록되지 않습니다 .

그렇지 않으면 App.config 를 클래스 라이브러리에 추가 해도 아무 작업도 수행되지 않습니다.


2

app.config의 비 수동 생성에 대한 대답은 Visual Studio 프로젝트 속성 / 설정 탭입니다.

설정을 추가하고 저장하면 app.config가 자동으로 생성됩니다. 이 시점에서 설정에 해당하는 속성을 포함 하는 { yourclasslibrary .Properties} 네임 스페이스 에 코드 묶음이 생성됩니다 . 설정 자체는 app.config의 applicationSettings 설정에 배치됩니다.

 <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <section name="ClassLibrary.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
</configSections>
<applicationSettings>
    <ClassLibrary.Properties.Settings>
        <setting name="Setting1" serializeAs="String">
            <value>3</value>
        </setting>
    </BookOneGenerator.Properties.Settings>
</applicationSettings>

Setting1 = 3이라는 응용 프로그램 범위 설정을 추가 한 경우 Setting1이라는 속성이 생성됩니다. 이러한 속성은 바이너리의 컴파일 부분이되고 개발시 지정한 값으로 설정된 DefaultSettingValueAttribute 로 장식됩니다 .

     [ApplicationScopedSetting]
    [DebuggerNonUserCode]
    [DefaultSettingValue("3")]
    public string Setting1
    {
        get
        {
            return (string)this["Setting1"];
        }
    }

따라서 클래스 라이브러리 코드에서와 같이 런타임 구성 파일에 해당 설정이없는 경우 이러한 속성을 사용하면 기본값을 사용하도록 대체됩니다. 이렇게하면 설정 항목이 없어서 응용 프로그램이 충돌하지 않습니다. 이는 이러한 작업이 어떻게 작동하는지 처음에 매우 혼란스럽게 할 수 있습니다. 이제 배포 된 라이브러리에서 우리 자신의 새 값을 지정하고 기본 설정 값이 사용되는 것을 피할 수있는 방법을 스스로에게 묻고 있습니다.

이는 실행 파일의 app.config를 올바르게 구성 할 때 발생합니다. 두 단계. 1. 해당 클래스 라이브러리에 대한 설정 섹션이 있음을 인식하고 2. 약간 수정하여 실행 가능한 구성에 클래스 라이브러리의 구성 파일을 붙여 넣습니다. (클래스 라이브러리 구성 파일을 외부에 유지하고 실행 파일의 구성에서 참조 할 수있는 방법이 있습니다.

따라서 클래스 라이브러리에 대한 app.config를 가질 수 있지만 상위 응용 프로그램과 제대로 통합하지 않으면 쓸모가 없습니다. 내가 언젠가 썼던 것을 여기에서보십시오 : link


1

솔루션에 클래스 라이브러리 프로젝트를 추가 할 때 app.config 파일이 자동으로 추가되지 않습니다.

내가 아는 한 수동으로 수행하는 것에 대한 반대 표시는 없습니다. 나는 이것이 일반적인 사용법이라고 생각합니다.

log4Net 구성에 대해서는 구성을 app.config에 넣을 필요가 없습니다. 프로젝트에 전용 conf 파일과 app.config 파일을 동시에 둘 수 있습니다.

이 링크 http://logging.apache.org/log4net/release/manual/configuration.html 은 두 가지 방법에 대한 예제를 제공합니다 (app.config 및 독립형 log4net conf 파일의 섹션).


app.config도서관 프로젝트에 를 추가해도 아무런 문제가되지 않습니다. 그러나 어느 쪽도 사용되지 않을 것입니다.
Andrew Barber

1
@AndrewBarber 테스트 프로젝트에서 사용됩니다. stackoverflow.com/a/31389495
binki

0

Properties.Settings를 사용하여 클래스 라이브러리 내부에 ConnectionStrings 등과 같은 값을 저장하는 것이 좋습니다. 예를 들어 테이블 어댑터를 추가하려고 할 때 Visual Studio의 제안에 따라 모든 연결 문자열이 저장됩니다. 여기에 이미지 설명 입력

그런 다음 clas 라이브러리의 모든 곳에서이 코드를 사용하여 액세스 할 수 있습니다.

var cs=  Properties.Settings.Default.[<name of defined setting>];
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.