settings.default. 영구 저장소에서 값 대신 기본값을 항상 반환합니다 (XML 파일)

StackOverflow https://stackoverflow.com/questions/192641

문제

최근에 IP 주소가 필요한 클래스가 포함 된 C# (.NET 2.0)에서 DLL을 썼습니다. 내 동료는 ".dll.config"(xml) 파일에서 IP를 검색하도록 클래스를 변경했습니다. 이것은 그가 만든 "응용 프로그램 설정"파일 (settings1.settings)에 의해 자동으로 생성됩니다. 이것의 이점은 최종 사용자가 XML/Config 파일의 IP 주소를 마음대로 변경할 수 있도록하는 것이 었습니다.

불행히도, 그의 코드에서 트리에서 그의 코드를 확인 하고이 새 코드를 컴파일 (또는 사용)하려고 할 때이 DLL을 호출하는 응용 프로그램은 파일의 값보다는 기본값 만 가져옵니다.

구성 파일을 호출하는 생성자는 다음과 같습니다.

    public class form : System.Windows.Forms.Form
    {
        public form()
        {
            // This call is required by the Windows Form Designer.
            InitializeComponent();
            IP = IPAddress.Parse(Settings1.Default.IPAddress);
        }
    }

나는 찾았다 MSDN 포럼 에서이 문제에 대한 참조 사용자가 말한 곳 :

'오래된'값 (개발 시간에 정의하는 값)은 하드 코딩됩니다. Franework가 구성 파일에 액세스하거나 열 수 없으면 대신 기본값을 사용합니다. DLL에서 설정을 사용하는 경우 항상 발생합니다.

  1. 이것은 구성 파일에 DLL의 외부 값을 저장할 수 없다는 것을 의미합니까? (내 동료는 어떻게 든이 일을 만들었습니다 ...)

  2. 내 프레임 워크가 구성 파일에 액세스하거나 열 수없는 것처럼 보이므로 왜 실패한 이유를 어떻게 알 수 있습니까? 아니면 이런 일이 발생할 때도 감지합니까?

데커: 약간 도움이됩니다. 불행히도이 DLL을 사양에 작성하고 있으므로 실제로 응용 프로그램의 구성 파일에 액세스 할 수 없습니다. 위에서 언급했듯이 내 동료는 "설정을 만들었습니다.1.Settings "파일. 당시에는 이해하지 못했지만 이제"1 "을 추가하면 호출하는 응용 프로그램의 설정 공간에서 벗어나는 것 같습니다.

내가 알아 내려고하는 것은 DLL이 동일한 디렉토리 옆에있는 구성 파일을 찾지 않는 이유라고 생각합니다. 코드를 통해 단계별로 추적하면 아무것도 드러나지 않습니다.

제쳐두고, 어셈블리의 "출력 유형"을 "클래스 라이브러리"에서 "Windows Application"으로 변경하고 DLL 코드의 시작 부분에 다음 줄을 추가 할 수 있습니다.

    [STAThread]
    public static void Main(string[] args)
    {
        System.Windows.Forms.Application.Run(new form());
    }

이것을 실행하면 다른 구성 파일 (a ".exe.config")을 생성하고 파일에서 새 데이터를 변경할 수 있습니다. 그래서 나는 약간 혼란 스러워요. 어떤 아이디어?

도움이 되었습니까?

해결책

프로토 타이핑 중에있는 응용 프로그램 에서이 정확한 문제를 해결하고 있습니다. 구성 파일을 해킹하겠다는 Decker의 제안은 작동해야하지만, 이것이 빌드주기의 일부로 수행 할 수있는 매우 불편한 수동 해킹이라고 생각합니다. 그 대신에 가장 깨끗한 솔루션은 각 라이브러리가 자체 라이브러리를 구문 분석하도록하는 것입니다 .dll.config 파일. 여전히 완벽하지 않으며 추가 보일러 플레이트 코드가 필요하지만 .NET 이이 app.config 파일을 처리하는 비잔틴 방식을 돌아 다니는 유일한 방법 인 것 같습니다.

다른 팁

나는이 기술을 항상 사용합니다. 종종 특정 설정이 필요한 라이브러리 어셈블리가 있으며, 웹 프로젝트 또는 Windows 서비스 프로젝트 인 주요 "실행 파일"어셈블리뿐만 아니라 프로젝트를 테스트하여 설정해야합니다.

모든 프로젝트에 대한 설정 파일을 만들 때 응용 프로그램 구성 파일이 추가됩니다. 모든 설정에 대해 입력 한 값은 구성 파일 및 설정 인프라에서 생성 된 클래스의 속성 (두 위치)에 저장됩니다. 구성 파일을 찾을 수 없으면 속성에 포함 된 값이 사용됩니다.

다음은 그러한 속성을 보여주는 스 니펫입니다.

다음은 생성 된 클래스에서 concordanceservicesendpointname의 기본값을 보여주는 스 니펫입니다.

    [global::System.Configuration.ApplicationScopedSettingAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Configuration.DefaultSettingValueAttribute("InternalTCP")]

    public string ConcordanceServicesEndpointName {
        get {
            return ((string)(this["ConcordanceServicesEndpointName"]));
        }
    }

원하는 것은 Library Assembly 프로젝트에서 app.config 파일에서 구성 섹션을 복사하여 메인 어셈블리의 해당 Web.config 또는 App.Config로 (신중하게) 병합하는 것입니다. 런타임에 사용되는 유일한 구성 파일입니다.

예는 다음과 같습니다.

<configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="LitigationPortal.Documents.BLL.DocumentsBLLSettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <applicationSettings>
    <LitigationPortal.Documents.BLL.DocumentsBLLSettings>
      <setting name="ConcordanceServicesEndpointName" serializeAs="String">
        <value>InternalTCP</value>
      </setting>
    </KayeScholer.LitigationPortal.Documents.BLL.DocumentsBLLSettings>
  </applicationSettings>

이 섹션을 "True"구성 파일로 복사해야합니다.

나는 오랫동안이 같은 문제를 겪었습니다. 성가시다.

나는 자신의 구성 파일을 만들고 각 DLL이 구문 분석하는 아이디어를 좋아하지만 구성을 변경하는 것이 쉽지 않을 수 있습니다.

과거에 내가 최소한 이것을 조금 더 쉽게 만들기 위해 내가 한 한 가지는 setting1.settings 파일이 유효하지 않은지 확인하는 것입니다.

예를 들어, LINQ-to-SQL을 사용하여 DB와 대화하는 클래스가 있습니다. 따라서 설정 1이 있습니다. 연결 문자열을 데이터베이스에 저장하는 파일을 설정합니다. 입력 한 기본값 (데이터베이스 테이블을 디자이너로 드래그하고 삭제할 때)은 DEV 데이터베이스의 연결 문자열입니다.

테스트 데이터베이스를 기반으로 DBML 파일을 생성 한 후에는 설정 파일을 편집하고 편집하고 "가짜_database"와 같은 데이터베이스 이름을 입력 할 수 있습니다.

이렇게하면 다른 프로젝트에서 DLL을 사용한 다음 구성 파일을 병합하여 DLL에 대한 적절한 구성 값을 추가하는 것을 잊어 버리면 "가짜 _Database에 연결할 수 없음"과 같은 오류가 발생합니다.

물론 디자이너와 다시 작업 해야하는 경우 값을 DEV 데이터베이스의 값으로 다시 변경해야합니다.

큰 고통. 그들은 어떻게 든 이것을 바꿔야합니다.

분명히 응용 프로그램은 기본 구성 파일 (아마도 응용 프로그램의 구성 파일)에서 읽으려고합니다. 확인하려면 DLL의 구성 파일에 DLL의 구성 파일에 키 값 쌍을 추가하고 응용 프로그램을 실행하고 이번에 읽은 지 확인하십시오.

왜 이것이 내 DLL과 테스트 응용 프로그램에서 작동하지 않는지에 대한 설명을 발견했다고 생각합니다. 다음은 결론 예외입니다 어떤 남자의 블로그:

이에 대한 수정은 응용 프로그램과 지원 어셈블리에 동일한 네임 스페이스를 갖도록하거나 AppName.exe.config 및 dllname.dll.config의 내용을 병합하는지 확인하는 것입니다 (예 .dll을 컴파일하면 이제 생성됩니다. 그러나이 파일은 응용 프로그램 디렉토리에 복사하고 자동으로 병합되지 않으면 무시됩니다).

따라서 DLL과 응용 프로그램을 동일한 네임 스페이스로 유지해야합니다.

(이런 종류의 DLL의 목적을 물리 치지 않습니까? DLL이 독립적 인 도서관이라고 생각했습니다.)

아마도 이것이 내 동료에게 효과가있는 이유 일 것입니다. 프로덕션 응용 프로그램은 DLL과 동일한 네임 스페이스를 공유합니다. (내 테스트 앱은 분명히 ...)

업데이트: 나는 최근에 내 동료와 함께 앉아서이 문제에 대해 다시 이야기했지만 그에게도 효과가 없었던 것 같지만, 그는 초기 가치를 장치와 동일하게 설정했기 때문에 그것을 깨닫지 못했습니다. 사용하려고했습니다. 물론 처음에는 작동하는 것처럼 보였지만 약간 다른 설정으로 다른 곳에 배치하자마자 다시 고장났습니다.

App.Config를 사용할 때 비슷한 문제를 보았습니다. Visual Studio 대신 .exe에서 응용 프로그램을 실행하고 예상대로 작동하는지 확인하십시오.

DLL에는 Access Modifier (Settings1.settings)가 내부 (VB의 친구)로 설정되어있을 수 있습니다. 액세스 수정자를 공개로 변경하고 응용 프로그램에서 DLL의 구성에서 값을 읽고 읽을 수 있는지 확인하십시오.

하워드의 대답은 이론을 다룹니다.

이것을 해결하는 빠르고 더러운 방법 중 하나는 XML 구성 파일을 수동으로 구문 분석하는 것입니다.

    string configFile = Assembly.GetExecutingAssembly().Location + ".config";
    XDocument.Load(configFile).Root.Element("appSettings")....

내가 당신이하는 실수는 당신이 분명히 당신이 분명히 DLL 설정을 통해 언급하는 것입니다. Settings1.Default.IPAddress 당신은 단순히이 작업을 수행하기 위해 자랑스러워하는 동안 Settings1.IPAddress.

차이점은 사용할 때입니다 Settings1.Default.IPAddress 값은 어셈블리 파일 (.dll 또는 .exe)에 내려진 하드 코드 값에서 속성 [global :: system.configuration.defaultsettingvalueattribute (...)]에서 얻습니다.

하는 동안 Settings1.IPAddress 파일에서 편집 할 수있는 값입니다 .dll.config (xml 파일) **. 따라서 XML 파일에 대한 변경 사항은 어셈블리의 하드 코드 기본값으로 반영되지 않습니다.

이거 말고:

IP = IPAddress.Parse(Settings1.Default.IPAddress);

그러나 이것을 시도하십시오 :

*IP = IPAddress.Parse(Settings1.IPAddress);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top