回答:
あなたはできる別の設定ファイルを持っていますが、「手動」それを読む必要があるでしょう、ConfigurationManager.AppSettings["key"]
だけで実行されているアセンブリの設定を読み込みます。
IDEとしてVisual Studioを使用していると仮定すると、目的のプロジェクトを右クリック→追加→新しい項目→アプリケーション構成ファイル
これ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名前空間への参照を追加する必要があります。
プロジェクトをビルドするときは、DLLに加えて、DLL DllName.dll.config
とともに公開する必要のあるファイルもファイルに含めます。
残念ながら、実行可能ファイルごとに作成できるapp.configファイルは1つだけなので、アプリケーションにDLLがリンクされている場合、独自のapp.configファイルを作成することはできません。
解決策は次のとおり
です。クラスライブラリのプロジェクトにApp.configファイルを配置する必要はありません。
クラスライブラリのdllを参照しているアプリケーションにApp.configファイルを配置します。
たとえば、次のように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を使用します。あなたはそれをあなたが望むすべてのものと呼ぶことができます。構成が「静的」であり、変更する必要がない場合は、組み込みリソースとしてプロジェクトに追加することもできます。
それがいくつかのアイデアを与えることを願って
ConfigurationSettings
現在は廃止と置き換えられているConfigurationManager
同等のが今ことになるので、ConfigurationManager.AppSettings
構成ファイルは、アプリケーションスコープであり、アセンブリスコープではありません。したがって、ライブラリを使用しているすべてのアプリケーションの構成ファイルに、ライブラリの構成セクションを配置する必要があります。
つまりappSettings
、クラスライブラリのアプリケーションの構成ファイル、特にセクションから構成を取得することはお勧めしません。ライブラリにパラメータが必要な場合は、ライブラリを呼び出す人がコンストラクタやファクトリメソッドなどのメソッド引数として渡す必要があります。これにより、呼び出し側のアプリケーションが、クラスライブラリが予期していた構成エントリを誤って再利用するのを防ぎます。
そうは言っても、XML構成ファイルは非常に便利なので、カスタム構成セクションを使用するのが私が見つけた最良の妥協案です。ライブラリーの構成を、フレームワークによって自動的に読み取られて解析されるXMLファイルに入れれば、潜在的な事故を回避できます。
あなたは上のカスタム構成セクションについての詳細を学ぶことができMSDNともフィル・ハークは素晴らしいの記事があり、それらのを。
appSettings
、慣習に基づくの代わりに、カスタムセクションが優れた代替手段を提供するということです。結局のところ、ASP.NETメンバーシップが使用するものとほぼ同じです。
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");
Visual Studioのクラスライブラリプロジェクト(プロジェクトのプロパティ、設定)に設定を追加すると、関連するuserSettings / applicatioNSettingsセクションを含むapp.configファイルがプロジェクトに追加され、これらの設定のデフォルト値がSettings.settingsから追加されます。ファイル。
ただし、この構成ファイルは実行時に使用されません。代わりに、クラスライブラリはそのホストアプリケーションの構成ファイルを使用します。
このファイルを生成する主な理由は、ホストアプリケーションの構成ファイルに設定をコピーして貼り付けることができるためです。
現在、小売ソフトウェアブランドのプラグインを作成しています。これは実際には.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の功績
私は同じ問題に直面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");
アセンブリには、独自の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は、アプリケーションの構成ファイルからその値を取得します。このアセンブリを使用するアプリケーションのいずれかが構成ファイルでその設定を欠いている場合、例外が発生しますo何かが欠落していることは明らかです。
MissingConfigFileAppSettingsはカスタム例外です。別の例外をスローすることもできます。
もちろん、より良い設計は、これらのクラスのメソッドに、構成ファイルの設定に依存するのではなく、パラメーターとしてこれらの値を提供することです。このようにして、これらのクラスを使用するアプリケーションは、これらの値を提供する場所と方法から決定できます。
前文: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");
私の知る限り、ライブラリ.configから必要なセクションをコピーして、アプリケーションの.configファイルに貼り付ける必要があります。実行可能なインスタンスごとに1つのapp.configのみを取得します。
使用しない理由:
[ProjectNamespace].Properties.Settings.Default.[KeyProperty]
C#の場合My.Settings.[KeyProperty]
VB.NETデザインタイムにこれらのプロパティを視覚的に更新する必要があります。
[Solution Project]->Properties->Settings
構成からの使用は、次のように非常に簡単でなければなりません。
var config = new MiniConfig("setting.conf");
config.AddOrUpdate("port", "1580");
if (config.TryGet("port", out int port)) // if config exist
{
Console.Write(port);
}
詳細については、MiniConfigを参照してください
string exeConfigPath = this.GetType().Assembly.Location;
のようなものに:string exeConfigPath = @"C:\MyFolder\DllFolder\ExeName.exe";