クラスライブラリのapp.config


83

VS2008ウィザードによってクラスライブラリ用に生成されたapp.configファイルが表示されません。私の調査では、アプリケーションにはapp.configが1つしか存在しないことがわかりました。

app.configを手動でクラスライブラリに追加するのは悪いことですか、それともクラスライブラリでapp.configの目的を果たす他のメソッドはありますか?

log4net構成情報をapp.configファイル内に保存する必要があります。


3
ライブラリから実行可能プロジェクト構成ファイルを読み取ることができます。
Akram Shahda 2011

回答:


102

通常、クラスライブラリプロジェクトにファイルを追加しないでくださいapp.config。それはあなたの側にいくらかの痛みを伴う曲げやねじれがなければ使用されません。それは図書館プロジェクトをまったく傷つけません-それはただ何もしません。

代わりに、ライブラリを使用しているアプリケーションを構成します。したがって、必要な構成情報はそこにあります。ライブラリを使用する可能性のあるアプリケーションごとに要件が異なる可能性があるため、これも実際には論理的に意味があります。


23
よかったね。しかし、私はあなたの質問に答えていませんでした。あなたは明らかに、ここで質問をしている人には当てはまらない、ある種の自家製の構成システムを持っています。
Andrew Barber

1
すべてのテストケースでNUnitから実行するSeleniumWebDriverクラスライブラリがあります。NUnitでの構成の設定について心配する必要はありません。これを行うには、どうすれば曲げたりねじったりできますか?:-)
MacGyver 2012年

3
理解しました... NUnitを使用している場合は、app.configファイルに* .nunitプロジェクトのファイル名と同じ名前を付けます。したがって、たとえば、プロジェクトを「ClassLibraryA.nunit」と呼んだ場合は、クラスライブラリ構成ファイルに「ClassLibraryA.config」という名前を付けます。また、同じフォルダ/ディレクトリに存在する必要があります。NUnitは実際にこれをメイン構成ファイルとして使用しています.... System.Configurationへの参照を追加し(.NETタブ内)....そして次のコードを使用します:string settingsValue = 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を作成しましたが、Webサービス関数を呼び出そうとするとアプリケーションがクラッシュしました
構成

クラスライブラリapp.configに配置された要素を、クラスライブラリの呼び出し元のapp.configまたはweb.configにコピーする必要があります。これにより、呼び出し元が構成を制御できるようになります。たとえば、呼び出し元はクラスライブラリが呼び出すサービスのURLを変更できるようになり、クラスライブラリはその変更についてさえ知りません。
ジョンサンダース

6
@ジョンサンダース:「必要かもしれない」はまさに正しい言葉です。そのため、構成設定がサーバーごとにのみ異なる場合があり(接続文字列など)、dllを使用するアセンブリごとに何度もコピーするよりも、dllに独自の構成を設定する方が便利です。私の意見では、Microsofts /.NETの推奨される使用法は聖杯ではありません。それは本当に、展開シナリオで最も便利なものに依存します。トッドに告げる必要はありません。彼の意見はあなたやマイクロソフトと同じくらい重要です。

私はこのソリューションに本当に興味があります-それは私にとって理想的に聞こえます。ライブラリがデフォルト設定を保持し、アプリケーションがそれらをオーバーライドする機能を備えていることは理にかなっています。ライブラリのapp.configから実行中のアセンブリのapp.configに設定を伝達する方法を拡張しますか、それとも関連するリソースに誘導しますか?
2014年

@crush:「コピーアンドペースト」と呼ばれます。.NETの強く型付けされた設定機能は、デフォルト値をアセンブリに組み込むため、少し役立ちます。
ジョンサンダース2014年

43

ジョン、あなたの質問に正しく答えなかった多くの意見が出されました。

私は私の意見を述べ、それからあなたが求めたことを正確に行う方法をあなたに教えます。

アセンブリが独自の構成ファイルを持つことができなかった理由はわかりません。アトミックの最初のレベル(それは本当の言葉ですか?)がアプリケーションレベルにあるのはなぜですか?なぜソリューションレベルではないのですか?これは恣意的で最善の判断であり、そのため意見です。ロギングライブラリを作成し、その構成ファイルを含めたい場合、それはグローバルに使用されますが、組み込みの設定機能にフックできないのはなぜですか?私たちはすべてそれを行いました...他の開発者に「強力な」機能を提供しようとしました。どうやって?本質的に制限に変換される仮定を行うことによって。これは、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:あなたの意見自体は重要ではありません。事実は重要だろう。.NETは、1日目以降、ライブラリの呼び出し元がライブラリ内のアイテムの構成を決定するように作成されました。ライブラリの呼び出し元が異なれば異なる構成が必要になる可能性があるため、構成に実際に意味があるのはこれだけです。
ジョンサンダース

19
@JohnSaunders「ライブラリの呼び出し元が異なれば、異なる構成が必要になる場合があります。」正確には、それらは異なる構成を「必要とする」可能性があり、構成が呼び出し元に依存するすべての場合において、ロジックは完全に理にかなっています。ただし、構成がクラスライブラリの内部で使用される場合がいくつかあり、呼び出し元が何であっても、構成はまったく同じです。ライブラリを消費するアプリケーションが10個ある場合は、まったく同じ構成をコピーして10個の構成ファイルに貼り付けるのがさらに悪いでしょう。
wired_in

3
@ToddBeaulieu:あなたが欲しい言葉は「原子性」だと思います。
nicodemus13 2014

3
プラグインアーキテクチャでは、すべてのプラグインに独自の構成ファイルがあるかどうかは確かに理にかなっています。
Davatar 2016

4
@RMuesi誰もそれが決して変わらないと言った、ただそれが図書館の呼び出し元に依存しないというだけだ。ライブラリをデバッグするのか、製品リリースをデバッグするのかによって、構成が変わる可能性があります。構築する環境などによって変わる可能性があります。
wired_in 2017年

6

実際、実装しているクラスライブラリは、それを消費しているアプリケーション内のapp.configから情報を取得しているため、VSの.netでクラスライブラリの構成を実装する最も正しい方法は、でapp.configを準備することです。ライブラリ構成など、消費するすべてのものを構成するアプリケーション。

私はlog4netので少し働いている、と私は、アプリケーションを調製したものは、常にメインの内側にlog4netの設定のためのセクション持っていたことが分かったのapp.configを

この情報がお役に立てば幸いです。

また会い、見つけた解決策についてコメントを投稿してください。

編集:

次のリンクでは、あなたが持っている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と別のプロパティファイルがあります。
アメディオ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にも1行も記述する必要がありません。


2
これが最良の答えだと感じました...構成ファイルをライブラリに許可するかどうかを議論するのではなく...この答えは、Log4netを使用するというOPの質問に答えます
saurav

1
質問では例としてlog4netを使用しましたが、実際の質問は一般的な構成に関するものです。log4netに関する回答は実際には無関係だと思います。
binki 2018

4

実際、まれに、app.configをクラスライブラリに保存し(手動で追加することにより)、OpenExeConfigurationで解析することができます。

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

あなたは本当にこれの本当の必要性を見積もるべきです。抽象データの場合、これは最善の解決策ではありませんが、「構成セクション」は非常に役立つ可能性があります。

たとえば、Channel FactoryTに基づくUnityContainerとInjectionFactoryを使用するだけで、メタデータなしで分離されたN層WCFアーキテクチャを編成しました。[ServiceContract]インターフェイスと共通のapp.configのみを含むexternall ClassLibrarydllを順番に追加しました。 clientsectionからエンドポイントを読み取り、1か所で簡単に追加/変更できます。


3

トレーサー/ロガーを使用している場合は、App.configテストクラスライブラリに追加する必要があります。それ以外の場合、TestDriven.Netなどのテストランナーを介してテストを実行しても、何もログに記録されません

たとえばTraceSource、プログラムで使用していますが、トレース/ログ構成を含むApp.configファイルをテストクラスライブラリにも追加しない限り、テストを実行しても何もログに記録されません。

それ以外の場合、App.configをクラスライブラリに追加しても何も起こりません。


2

app.configを手動で作成しない場合の答えは、[VisualStudioプロジェクトのプロパティ/設定]タブです。

設定を追加して保存すると、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を適切に構成したときに発生します。2つのステップ。1.そのクラスライブラリの設定セクションがあることを認識します。2。少し変更を加えて、クラスライブラリの構成ファイルを実行可能構成に貼り付けます。(クラスライブラリの設定ファイルを外部に保持し、実行可能ファイルの設定から参照するだけの方法があります。

したがって、クラスライブラリ用のapp.configを作成することはできますが、親アプリケーションと適切に統合しないと役に立ちません。私が以前書いたものをここで見てください:リンク


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 2018

0

Properties.Settingsを使用して、ConnectionStringsなどの値をクラスライブラリ内に格納することをお勧めします。これは、たとえばテーブルアダプターを追加しようとしたときに、VisualStudioからの提案によってすべての接続文字列が格納される場所です。 ここに画像の説明を入力してください

そして、クラスライブラリのどこでもこのコードを使用してアクセスできます

var cs=  Properties.Settings.Default.[<name of defined setting>];
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.