Эквивалент приложение.config ' для библиотеки (DLL)
есть ли эквивалент app.config
для библиотек (DLL)? Если нет, то каков самый простой способ хранения параметров конфигурации, специфичных для библиотеки? Пожалуйста, учтите, что библиотека может использоваться в различных приложениях.
14 ответов:
вы можете есть отдельный файл конфигурации, но вы должны будете прочитать его "вручную",
ConfigurationManager.AppSettings["key"]
читать только в конфигурации сборки.предполагая, что вы используете Visual Studio в качестве IDE, вы можете щелкнуть правой кнопкой мыши нужный проект → Добавить → новый элемент → файл конфигурации приложения
добавить
App.config
в папку проекта, поместите свои настройки там под . Если вы не используете Visual Studio и не добавляете файл вручную, обязательно дайте ему такое имя:DllName.файл DLL.конфигурации, иначе код не будет работать должным образом.теперь для чтения из этого файла есть такая функция:
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. Он будет содержать приложение.конфиг с записью такой как:
<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. После небольшого исследования и тестирования я составил следующий класс. Он делает свою работу безупречно. Обратите внимание, что я не реализовал локальную обработку исключений в моем случае, потому что я ловлю исключения на более высоком уровне.
некоторые настройки, возможно, необходимо, чтобы получить десятичную точку правильно, в случае десятичных знаков и удваивается, но он отлично работает для моей культуры...
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); } }
приложение.Пример файла конфигурации
<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