Эквивалентно " app.config ' для библиотеки (DLL)
есть ли эквивалент app.config
для библиотек (DLL)? Если нет, то каков самый простой способ хранения параметров конфигурации, специфичных для библиотеки? Пожалуйста, учтите, что библиотека может использоваться в разных приложениях.
14 ответов
вы can есть отдельный файл конфигурации, но вам придется прочитать его "вручную",ConfigurationManager.AppSettings["key"]
читать только в конфигурации сборки.
предполагая, что вы используете Visual Studio в качестве IDE, вы можете щелкнуть правой кнопкой мыши нужный проект → Добавить → новый элемент → файл конфигурации приложения
добавить App.config
в папку проекта, поместите свои настройки там под . Если вы не используете Visual Studio и не добавляете файл вручную, обязательно дайте ему такое имя:имя-DLL.файл 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");
...
}
вы также должны добавить ссылку на System.Пространство имен конфигурации для того, чтобы класс ConfigurationManager был доступен.
при строительстве проект, в дополнение к DLL у вас будет DllName.dll.config
файл, а также, это файл, который вы должны опубликовать с самой DLL.
выше основной пример кода, для тех, кто заинтересован в полномасштабном примере, пожалуйста, обратитесь к этот и другие ответы.
к сожалению, вы можете иметь только одно приложение.конфигурационный файл на исполняемый файл, поэтому, если у вас есть DLL, связанные с вашим приложением, они не могут иметь свое собственное приложение.конфигурационный файл.
решение:
Вам не нужно ставить приложение.файл конфигурации в проекте библиотеки классов.
Вы ставите приложение.файл конфигурации в приложении, ссылающемся на ваш класс
DLL-файл библиотеки.
например, предположим, что у нас есть библиотека классов с именем MyClasses.dll, которая использует приложение.конфигурационный файл так:
string connect =
ConfigurationSettings.AppSettings["MyClasses.ConnectionString"];
теперь предположим, что у нас есть приложение Windows с именем MyApp.exe, которые ссылки на MyClasses.файл DLL. Он будет содержать приложение.config с помощью записи as:
<appSettings>
<add key="MyClasses.ConnectionString"
value="Connection string body goes here" />
</appSettings>
или
xml-файл является лучшим эквивалентом для приложения.конфиг. Использовать сериализацию/десериализацию xml как необходимый. Ты можешь называть это как хочешь. Если ваша конфигурация " статическая" и не нужно менять, вы также можете добавить его в проект как - внедренный ресурс.
надеюсь, это дает некоторое представление
файлы конфигурации относятся к области приложения, а не к области сборки. Поэтому вам нужно будет поместить разделы конфигурации вашей библиотеки в файл конфигурации каждого приложения, использующего вашу библиотеку.
тем не менее, это не хорошая практика, чтобы получить конфигурацию из файла конфигурации приложения, особенно в библиотеке классов. Если вашей библиотеке нужны параметры, они, вероятно, должны быть переданы в качестве аргументов метода в конструкторах, заводских методах, так далее. тем, кто звонит в вашу библиотеку. Это предотвращает случайное повторное использование записей конфигурации, ожидаемых библиотекой классов, вызывающими приложениями.
тем не менее, файлы конфигурации XML чрезвычайно удобны, поэтому лучший компромисс, который я нашел, - это использование пользовательских разделов конфигурации. Вы можете поместить конфигурацию своей библиотеки в XML-файл, который автоматически считывается и анализируется платформой, и вы избегаете потенциальных аварий.
вы можете узнать подробнее о пользовательских разделах конфигурации на MSDN и у Фила Хаака есть хорошая статья на них.
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 и значениями по умолчанию для этих параметров из ваших параметров.файл настроек.
однако этот файл конфигурации не будет использоваться во время выполнения-вместо этого библиотека классов использует файл конфигурации своего хост-приложения.
Я считаю главной причиной этот файл создается для копирования / вставки параметров в файл конфигурации хост-приложения.
в ответ на исходный вопрос я обычно добавляю файл конфигурации в мой тестовый проект в качестве ссылки; затем вы можете использовать атрибут DeploymentItem для добавления в папку Out тестового запуска.
[TestClass]
[DeploymentItem("MyProject.Cache.dll.config")]
public class CacheTest
{
.
.
.
.
}
в ответ на комментарии, что сборки не могут быть специфичными для проекта, они могут, и это обеспечивает большую гибкость esp. при работе с фреймворками МОК.
сборки не имеют собственного приложения.конфигурационный файл. Они используют приложение.файл конфигурации приложения, которое их использует. Поэтому, если ваша сборка ожидает определенных вещей в файле конфигурации, просто убедитесь, что в файле конфигурации вашего приложения есть эти записи.
Если ваша сборка используется несколькими приложениями, то каждое из этих приложений должно иметь эти записи в своем приложении.конфигурационный файл.
что я бы рекомендовал вам сделать, это определить свойства классов в вашей сборке для этих значений, например
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 является пользовательским исключением. Возможно, вы захотите создать другое исключение.
конечно лучший дизайн было бы для метода этих классов, чтобы предоставить эти значения в качестве параметров, а не полагаться на настройку файла конфигурации. Таким образом, приложения, использующие эти классы, могут решить, откуда и как они предоставляют эти значения.
используйте добавить существующий элемент, выберите конфигурацию приложения из проекта dll. Перед нажатием кнопки Добавить используйте маленькую стрелку вниз в правой части кнопки Добавить, чтобы "добавить как ссылку"
Я делаю это все время в моем dev.
В настоящее время я создаю плагины для торговой марки программного обеспечения, которые на самом деле являются библиотеками классов .net. Как требование, каждый плагин должен быть настроен с помощью файла config. После небольшого исследования и тестирования я составил следующий класс. Он делает свою работу безупречно. Обратите внимание, что я не реализовал локальную обработку исключений в моем случае, потому что я ловлю исключения на более высоком уровне.
некоторые настройки, возможно, необходимо, чтобы получить десятичную точку правильно, в случае десятичных знаков и удваивается, но отлично работает для моего 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
преамбула: Я использую NET 2.0;
решение опубликовано Яннис Leoussis приемлемо, но у меня были некоторые проблемы с ним.
сначала static AppSettingsSection AppSettings = (AppSettingsSection)myDllConfig.GetSection("appSettings");
возвращает значение null. Мне пришлось изменить его на static AppSettingSection = myDllConfig.AppSettings;
тут return (T)Convert.ChangeType(AppSettings.Settings[name].Value, typeof(T), nfi);
нет catch для исключения. Поэтому я изменил его
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");
насколько мне известно, вам нужно скопировать + вставить разделы, которые вы хотите из библиотеки .настроек в приложениях .конфигурационный файл. Вы получаете только 1 приложение.конфигурация на исполняемый экземпляр.
я столкнулся с той же проблемой и решил ее, создав статические параметры класса после добавления файла конфигурации приложения в проект:
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");
почему бы не использовать:
-
[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