Эквивалентно " 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