197

app.config ファイルを DLL に追加しようとしていますが、すべて失敗しました。

MusicGenesis の「Putting configuration information in a DLL」によると、これは問題にならないはずです。だから明らかに私は何か間違ったことをしている...

次のコードは、DLL から ConnectionString を返す必要があります。

return ConfigurationManager.AppSettings["ConnectionString"];

ただし、app.config ファイルをコンソール アプリケーションにコピーすると、正常に動作します。

何か案は?

4

17 に答える 17

105

ルート アプリケーションの web.config または app.config からではなく、DLL の構成ファイルから設定を読み取りたい場合は、以下のコードを使用して dll の構成を読み取ります。

var appConfig = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location);
string dllConfigData = appConfig.AppSettings.Settings["dllConfigData"].Value;
于 2010-02-16T11:53:24.177 に答える
22

私は同じ問題を抱えていて、ウェブを数時間検索しましたが、解決策が見つからなかったので、自分で作成しました. なぜ .net 構成システムがそれほど柔軟性に欠けるのか疑問に思いました。

背景: DAL.dll に、データベースと DAL 設定用の独自の構成ファイルを持たせたいと考えています。Enterprise Library とその独自の構成用の app.config も必要です。したがって、app.config と dll.config の両方が必要です。

私がやりたくなかったのは、すべてのプロパティ/設定をアプリから DAL レイヤーにパススルーすることです!

通常のapp.configの動作に必要なため、「AppDomain.CurrentDomain.SetupInformation.ConfigurationFile」を曲げることはできません。

私の要件/視点は次のとおりです。

  • ClassLibrary1.dll.config から WindowsFormsApplication1.exe.config への手動コピーは、他の開発者には再現できないためです。
  • これは主要な機能であり、それを失いたくなかったので、強力な型付け "Properties.Settings.Default.NameOfValue" (設定の動作) の使用を保持します。
  • 独自の/カスタム構成ファイルまたは管理を挿入するための ApplicationSettingsBase がないことがわかりました (これらのクラスでは、必要なフィールドはすべてプライベートです)
  • ClassLibrary1.dll.config をコピー/書き換えて、いくつかのセクションに複数の XML ファイルを提供する必要があるため、「configSource」ファイル リダイレクトを使用することはできません (これも気に入りませんでした)。
  • MSDN が示唆するように、この単純なタスクのために独自の SettingsProvider を作成するのは好きではありませんでした。
  • 構成ファイルの applicationSettings セクションと connectionStrings セクションのみが必要です

そこで、Settings.cs ファイルを変更して、ClassLibrary1.dll.config を開いてプライベート フィールドのセクション情報を読み取るメソッドを実装しました。その後、"this[string propertyName]" をオーバーライドしたので、生成された Settings.Desginer.cs は基本クラスではなく、新しい Property を呼び出します。そこで、設定がリストから読み取られます。

最後に、次のコードがあります。

internal sealed partial class Settings
{
    private List<ConfigurationElement> list;

    /// <summary>
    /// Initializes a new instance of the <see cref="Settings"/> class.
    /// </summary>
    public Settings()
    {
        this.OpenAndStoreConfiguration();
    }

    /// <summary>
    /// Opens the dll.config file and reads its sections into a private List of ConfigurationElement.
    /// </summary>
    private void OpenAndStoreConfiguration()
    {
        string codebase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
        Uri p = new Uri(codebase);
        string localPath = p.LocalPath;
        string executingFilename = System.IO.Path.GetFileNameWithoutExtension(localPath);
        string sectionGroupName = "applicationSettings";
        string sectionName = executingFilename + ".Properties.Settings";
        string configName = localPath + ".config";
        ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
        fileMap.ExeConfigFilename = configName;
        Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

        // read section of properties
        var sectionGroup = config.GetSectionGroup(sectionGroupName);
        var settingsSection = (ClientSettingsSection)sectionGroup.Sections[sectionName];
        list = settingsSection.Settings.OfType<ConfigurationElement>().ToList();

        // read section of Connectionstrings
        var sections = config.Sections.OfType<ConfigurationSection>();
        var connSection = (from section in sections
                           where section.GetType() == typeof(ConnectionStringsSection)
                           select section).FirstOrDefault() as ConnectionStringsSection;
        if (connSection != null)
        {
            list.AddRange(connSection.ConnectionStrings.Cast<ConfigurationElement>());
        }
    }

    /// <summary>
    /// Gets or sets the <see cref="System.Object"/> with the specified property name.
    /// </summary>
    /// <value></value>
    public override object this[string propertyName]
    {
        get
        {
            var result = (from item in list
                         where Convert.ToString(item.ElementInformation.Properties["name"].Value) == propertyName
                         select item).FirstOrDefault();
            if (result != null)
            {
                if (result.ElementInformation.Type == typeof(ConnectionStringSettings))
                {
                    return result.ElementInformation.Properties["connectionString"].Value;
                }
                else if (result.ElementInformation.Type == typeof(SettingElement))
                {
                    return result.ElementInformation.Properties["value"].Value;
                }
            }
            return null;
        }
        // ignore
        set
        {
            base[propertyName] = value;
        }
    }

ClassLibrary1.dll.config を ClassLibrary1 出力ディレクトリからアプリケーションの出力ディレクトリにコピーするだけです。おそらく誰かがそれを便利だと思うでしょう。

于 2011-04-05T12:15:06.113 に答える
14

ConfigurationManager を使用する場合、プロセス/AppDomain構成ファイル (app.config / web.config) をロードしていると確信しています。特定の構成ファイルをロードする場合は、そのファイルを名前で指定する必要があります...

あなたは試すことができます:

var config = ConfigurationManager.OpenExeConfiguration("foo.dll");
config.ConnectionStrings. [etc]
于 2009-02-27T10:56:17.380 に答える
13

ConfigurationManager.AppSettings は、特定の DLL ではなく、アプリケーションに対して定義された設定を返します。それらにアクセスすることはできますが、返されるのはアプリケーション設定です。

別のアプリケーションから dll を使用している場合、ConnectionString はアプリケーションの app.settings にあります。

于 2009-02-27T10:58:02.117 に答える
7

これがパーティーに遅れていることは知っていますが、DLLに使用するソリューションを共有すると思いました。

私はどちらかというと KISS 派の考え方なので、.NET DLL が動作方法や移動先などを制御する外部データ ポイントを保存する必要がある場合は、パブリック プロパティのみを持つ "config" クラスを作成するだけです。必要なすべてのデータポイントを保存し、DLLの外部を制御して、変更を加えるために再コンパイルするのを防ぐことができるようにしたいと考えています。次に、.Net の XML Serializing を使用して、クラスのオブジェクト表現をファイルに保存および読み込みます。

シングルトン、静的ユーティリティ クラス、拡張メソッドなど、読み取りとアクセスを処理する方法は多数あります。これは、DLL がどのように構造化されているか、どのメソッドが DLL に最適かによって異なります。

于 2010-02-22T16:17:11.730 に答える
4

そうです、dll の構成ファイルを読み取ることができます。私の設定ファイルが問題であることがわかるまで、私はこれに1日苦労しました。以下の私のコードを参照してください。実行できました。

        ExeConfigurationFileMap map = new ExeConfigurationFileMap();
        map.ExeConfigFilename = Assembly.GetExecutingAssembly().Location + ".config";
        Configuration libConfig = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
        AppSettingsSection section = (libConfig.GetSection("appSettings") as AppSettingsSection);
        Console.WriteLine(section.Settings["dnd_shortcodes"].Value);

Plugin1.dll.configは以下のように見えました。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <appSettings>
  <add key="cmd_location" value="http://..."/>
  <add key="dnd_shortcodes" value="142,145,146,157,165,167,168,171,173,176,178,404,40"/>
 </appSettings>
</configuration>

私の構成ファイルには<appSettings>タグが欠けていることがわかったので、周りを見回してください。

于 2013-04-04T18:49:33.317 に答える
3

WCF など、舞台裏で大量の構成を検索するライブラリを使用している場合は、次のようにすることを検討してください。

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "MyWcfClientWrapper.dll.config");

または PowerShell で:

[AppDomain]::CurrentDomain.SetData("APP_CONFIG_FILE", "MyWcfClientWrapper.dll.config")

IMO この手法はコードのにおいがするものであり、実際にはアドホック スクリプトでの使用にのみ適しています。本番コードでこれを行いたい場合は、アーキテクチャのレビューを行う時期かもしれません。

以下はお勧めしません:
技術的な好奇心として、テーマのバリエーションを次に示します。DLL に格納されているクラスの 1 つに静的コンストラクターを作成し、そこからこの呼び出しを行うことができます。最後の手段を除いて、これを行うことはお勧めしません。

于 2011-06-19T22:01:04.423 に答える
3

アセンブリは一時キャッシュに存在するため、パスを結合して dll の構成を取得する必要があります。

var appConfig = ConfigurationManager.OpenExeConfiguration(
    Path.Combine(Environment.CurrentDirectory, Assembly.GetExecutingAssembly().ManifestModule.Name));
于 2010-05-26T03:01:07.393 に答える
3

この構成ファイルは、動作が開発環境から展開に変化するため、明確にするのが本当に混乱しているようです。どうやらDLLは独自の構成ファイルを持つことができますが、dllを(構成ファイルと一緒に)コピーして別の場所に貼り付けると、すべてが機能しなくなりました。唯一の解決策は、app.config ファイルを 1 つのファイルに手動でマージすることです。このファイルは、exec によってのみ使用されます。たとえば、myapp.exe には、myapp.exe によって使用されるすべての dll のすべての設定を含む myapp.exe.config ファイルがあります。私はVS2008を使用しています。

于 2009-09-25T15:47:24.803 に答える
2

この問題の良い解決策と思われるものを見つけました。VS 2008 C# を使用しています。私の解決策には、複数の構成ファイル間で個別の名前空間を使用することが含まれます。私のブログにソリューションを投稿しました: http://tommiecarter.blogspot.com/2011/02/how-to-access-multiple-config-files-in.html

例えば:

この名前空間は、dll 設定の読み取り/書き込みを行います。

var x = company.dlllibrary.Properties.Settings.Default.SettingName;
company.dlllibrary.Properties.Settings.Default.SettingName = value;

この名前空間は、exe 設定の読み取り/書き込みを行います。

company.exeservice.Properties.Settings.Default.SettingName = value;
var x = company.exeservice.Properties.Settings.Default.SettingName;

記事内で注意事項が記載されています。HTH

于 2011-02-09T00:19:17.613 に答える
1

Marc が言うように、これは不可能です (ただし、Visual Studio ではクラス ライブラリ プロジェクトにアプリケーション構成ファイルを追加できます)。

アセンブリ構成ファイルを可能にすると思われるAssemblySettingsクラスをチェックアウトすることをお勧めします。

于 2009-02-27T10:59:18.230 に答える
0

dll の場合、構成は dll ではなくアプリケーションによって所有されるため、構成に依存するべきではありません。

これはここで説明されています

于 2013-05-31T23:29:25.803 に答える
0

この投稿では、同様の問題が議論され、私の問題を解決する方法 別のアプリケーション設定ファイルを動的にロードして現在の設定とマージする方法? 役立つかもしれません

于 2011-11-20T10:59:17.793 に答える
0

このコードを使用できます:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace GClass1
{
[Guid("D6F88E95-8A27-4ae6-B6DE-0542A0FC7039")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface _GesGasConnect
{
    [DispId(1)]
    int SetClass1Ver(string version);


}

[Guid("13FE32AD-4BF8-495f-AB4D-6C61BD463EA4")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("InterfacesSMS.Setting")]
public class Class1 : _Class1
{
    public Class1() { }


    public int SetClass1(string version)
    {
        return (DateTime.Today.Day);
    }
}
}
于 2017-07-19T16:44:28.047 に答える