Существует ли эквивалент для app.config
для библиотек (DLL)? Если нет, то какой самый простой способ сохранить настройки конфигурации, специфичные для библиотеки? Пожалуйста, учтите, что библиотека может использоваться в разных приложениях.
Эквивалентен "app.config" для библиотеки (DLL)
Ответ 1
У вас может отдельный файл конфигурации, но вы должны будете прочитать его "вручную", ConfigurationManager.AppSettings["key"]
будет читать только конфигурацию запущенной сборки.
Предполагая, что вы используете Visual Studio в качестве среды IDE, вы можете щелкнуть правой кнопкой мыши по нужному проекту → Добавить → Новый элемент → Файл конфигурации приложения
Это добавит 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");
...
}
Вам также нужно добавить ссылку на пространство имен System.Configuration, чтобы иметь класс ConfigurationManager.
При создании проекта, помимо DLL, вы также будете иметь файл DllName.dll.config
, который вы должны опубликовать с самой DLL.
Вышеприведенный базовый пример кода для тех, кто интересуется полномасштабным примером, см. этот другой ответ.
Ответ 2
К сожалению, у вас может быть только один файл app.config для каждого исполняемого файла, поэтому, если у вас есть DLL файлы, связанные с вашим приложением, они не могут иметь свои файлы app.config.
Решение:
Вам не нужно класть файл App.config в проект библиотеки классов.
Вы помещаете файл App.config в приложение, ссылающееся на ваш класс
библиотека dll.
Например, скажем, у нас есть библиотека классов с именем MyClasses.dll, которая использует файл app.config следующим образом:
string connect =
ConfigurationSettings.AppSettings["MyClasses.ConnectionString"];
Теперь скажем, что у нас есть приложение Windows с именем MyApp.exe, которое ссылается на MyClasses.dll. Он будет содержать App.config с записью, такой как как:
<appSettings>
<add key="MyClasses.ConnectionString"
value="Connection string body goes here" />
</appSettings>
ИЛИ
Файл xml лучше всего подходит для app.config. Использовать xml serialize/deserialize as необходимо. Вы можете назвать это тем, что хотите. Если ваша конфигурация "статическая", и его не нужно менять, вы также можете добавить его в проект как встроенный ресурс.
Надеюсь, что это даст некоторую идею
Ответ 3
Конфигурационные файлы не привязаны к приложениям, а не в сборе. Поэтому вам нужно разместить разделы конфигурации библиотеки в каждом файле конфигурации приложения, использующем вашу библиотеку.
Тем не менее, неплохо было получить конфигурацию из файла конфигурации приложения, особенно раздела appSettings
, в библиотеке классов. Если вашей библиотеке нужны параметры, они, вероятно, должны передаваться как аргументы метода в конструкторах, методах factory и т.д. Тем, кто звонит в вашу библиотеку. Это предотвращает случайное повторное использование приложений приложения, которые ожидались в библиотеке классов.
Тем не менее, файлы конфигурации XML чрезвычайно удобны, поэтому лучший компромисс, который я нашел, - это использование настраиваемых разделов конфигурации. Вы можете разместить свою конфигурацию библиотеки в XML файле, который автоматически считывается и анализируется каркасом, и вы избегаете потенциальных аварий.
Подробнее о настраиваемых разделах конфигурации можно узнать на MSDN, а также У Фила Хаака есть хорошая статья.
Ответ 4
public class ConfigMan
{
#region Memberes
string _assemblyLocation;
Configuration _configuration;
#endregion
#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
#region Properties
Configuration Configuration
{
get
{
if (_configuration == null)
{
try
{
_configuration = ConfigurationManager.OpenExeConfiguration(_assemblyLocation);
}
catch (Exception exception)
{
}
}
return _configuration;
}
}
#endregion
#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
}
Просто для чего-то я реорганизовал верхний ответ в класс. Использование - это что-то вроде
ConfigMan configMan = new ConfigMan(this.GetType().Assembly.Location);
var setting = configMan.GetAppSetting("AppSettingsKey");
Ответ 5
Если вы добавите настройки в проект библиотеки классов в Visual Studio (Свойства проекта, Настройки), он добавит файл app.config в ваш проект с соответствующими разделами userSettings/applatioNSettings и значениями по умолчанию для этих параметров из вашего Файл настроек.
Однако этот файл конфигурации не будет использоваться во время выполнения - вместо этого библиотека классов использует файл конфигурации своего хостинга.
Я считаю, что основная причина для создания этого файла заключается в том, что вы можете скопировать/вставить настройки в файл конфигурации приложения хоста.
Ответ 6
В ответ на исходный вопрос я обычно добавляю файл конфигурации в свой тестовый проект как ссылку; вы можете использовать атрибут DeploymentItem для добавления в папку Out тестового прогона.
[TestClass]
[DeploymentItem("MyProject.Cache.dll.config")]
public class CacheTest
{
.
.
.
.
}
В ответ на комментарии, что сборки не могут быть специфичными для проекта, они могут и обеспечивают большую гибкость. при работе с каркасами IOC.
Ответ 7
В сборкахнет собственного файла 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 получает свое значение из файла конфигурации приложения. Если в каком-либо приложении, использующем эту сборку, отсутствует этот параметр в файле конфигурации, вы получите исключение, ясно, что что-то пропало.
MissingConfigFileAppSettings - это обычное исключение. Вы можете создать другое исключение.
Конечно, лучший дизайн был бы для того, чтобы метод этих классов предоставлял эти значения в качестве параметров, а не полагался на настройку файла конфигурации. Таким образом, приложения, использующие эти классы, могут решить, где и как они обеспечивают эти значения.
Ответ 8
Используйте добавление существующего элемента, выберите конфигурацию приложения из проекта dll. Прежде чем нажимать кнопку "Добавить", используйте маленькую стрелку вниз в правой части кнопки "Добавить в качестве ссылки"
Я делаю это все время в своем dev.
Ответ 9
В настоящее время я создаю плагины для бренда розничного программного обеспечения, которые на самом деле являются библиотеками классов .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");
Кредиты для мастера магии и MattC
Ответ 10
Преамбула: я использую 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);
не имеет 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");
Ответ 11
Насколько мне известно, вам нужно скопировать + вставить разделы, которые вы хотите, из библиотеки .config в файл .config приложений. Вы получаете только 1 app.config для исполняемого экземпляра.
Ответ 12
Я столкнулся с той же проблемой и разрешил ее, создав статический класс 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");