Как использовать разные файлы .settings для разных сред в .NET?

.NET позволяет использовать файлы .settings для управления настройками приложения. Я хотел бы хранить настройки производства, разработки и тестирования отдельно таким образом, чтобы я мог делать что-то вроде этого:

EnvironmentSettings environmentSettings;

// get the current environment (Production, Development or Test)
ApplicationEnvironment Environment = (ApplicationEnvironment)
    Enum.Parse(typeof(ApplicationEnvironment), Settings.Default.ApplicationEnvironment);

switch (Environment)
{
    case ApplicationEnvironment.Production:
        environmentSettings = Settings.Production;
        break;
    ...
}

string reportOutputLocation = environmentSettings.ReportOutputLocation;

По сути, мне нужны два отдельных класса настроек: общий класс настроек, который хранит выбранную среду и свойства, не относящиеся к среде, и 3 статических экземпляра второго класса, называемого EnvironmentSettings. Используемый экземпляр должен зависеть от среды, указанной в общем классе настроек.

Есть ли способ сделать это, кроме ручной установки значений для всех этих параметров в статическом конструкторе или что-то в этом роде? Если мне нужно это сделать, я бы предпочел иметь один большой класс настроек с такими свойствами, как «DevOutputLocation», «LiveOutputLocation» и т. Д.

У меня может быть несколько файлов .settings в моем проекте, но это просто создает отдельные классы, которые не являются производными друг от друга. Итак, я мог бы создать файлы DevelopmentSettings.settings, ProductionSettings.settings и TestSettings.settings и дать им одинаковые свойства, но тогда мне понадобится повсюду куча операторов switch, чтобы определить, какой класс использовать, потому что они не являются производными от общего класса. .


person Carl    schedule 11.02.2010    source источник
comment
вы могли бы сделать это, используя разных пользователей для каждой среды, но мне почему-то кажется, что это вызывает больше проблем, чем решает.   -  person John Knoeller    schedule 12.02.2010


Ответы (6)


Я использую этот подход для файлов .config, уверен, что он вам тоже поможет. Просто посмотрите сообщение в блоге Скотта Хансельмана и этот вопрос. Идеология чертовски проста, но работает неплохо. Все, что вам понадобится, это:

  1. создать несколько файлов для разных конфигураций
  2. назовите их по соглашению, например my.dev.settings, my.live.settings
  3. создать событие сборки публикации (см. ссылки)
  4. наслаждайтесь =)

Код создания экземпляра для вашего класса с настройками всегда будет выглядеть в настройках по умолчанию (которые будут заменяться после каждой сборки нужным), поэтому этот подход требует минимальных усилий.

person Restuta    schedule 12.02.2010
comment
Неужели это единственный способ? Полагаю, что если это одобрено Скоттом Х. Это кажется действительно грязным взломом. Можно подумать, что можно указать, какой файл .settings или .config использовать для каждой конфигурации сборки. - person Carl; 12.02.2010
comment
Я просто возвращался к своим ранее заданным вопросам и заметил, что никогда не отмечал это как отвеченный, так что готово. Еще раз спасибо. - person Carl; 06.07.2011
comment
Другой вариант - использовать инструмент преобразования XML, например SlowCheetah. - person Roger Stewart; 17.03.2015

Одна мысль заключается в том, что переключение между серией статических значений звучит как довольно чреватый способ делать что-то. Я бы посоветовал поискать паттерн Синглтон. Этот шаблон дает вам один экземпляр класса, который является общим для всех ссылок на класс, но при его первой загрузке вы можете выполнить свои обычные биты инициализации, чтобы проверить свою среду и установить значения соответственно.

Точно так же, вместо того, чтобы использовать переключатели для работы с разными классами, разве вы не хотели бы разрабатывать один интерфейс и каждый класс реализовывать этот интерфейс?

person David Burton    schedule 11.02.2010

Выполнение проверки, чтобы определить, в какой среде вы работаете, связано с небольшими накладными расходами. Если вы говорите о веб-среде, это может означать значительное снижение производительности. Я бы рекомендовал создать три отдельных файла конфигурации и настроить систему непрерывной интеграции и развертывания, которая обрабатывает присвоение имен и развертывание соответствующего файла настроек в зависимости от среды. В вашем случае у вас будет три файла: Production.config, Development.config и Test.config. Затем сервер интеграции создаст копию этого файла для web.config или app.config в зависимости от среды.

Что касается любого дополнительного обслуживания, связанного с поддержанием трех отдельных файлов при каждом изменении конфигурации, мы сохраняем файлы в автоматическом форматировании и используем что-то вроде WinMerge, чтобы легко видеть различия и поддерживать их надлежащую синхронизацию. Файлы такого типа обычно не требуют большого количества изменений, а когда и требуются, то обычно являются незначительными дополнениями.

person pdavis    schedule 12.02.2010

В настоящее время я делаю что-то похожее на решение, упомянутое pdavis. Но для упрощения нескольких файлов конфигурации я использую шаблоны T4 для создания файлов конфигурации для конкретной среды. Таким образом, существует один файл web.tt, который обрабатывает создание файла web.config по умолчанию. Каждая среда имеет свой собственный файл шаблона (qa.tt, production.tt и т. Д.), Который наследуется от web.tt и содержит любые переопределения для конкретной среды. Любые изменения в веб-конфигурации - новые параметры приложения, параметры конфигурации и т. Д. Автоматически распространяются на все файлы конфигурации для конкретного региона путем повторного создания шаблонов, и вам не нужно беспокоиться о синхронизации файлов с помощью инструмента сравнения.

person Matt Otto    schedule 13.02.2010

Просто идея, но может сработать ...

  • Вам понадобится N + 2 файла настроек (N разных сборок; 2 мастера) с одинаковыми ключами.

  • Очистите свойство «Custom Tool» для всех, кроме одного из мастеров (чтобы мастер генерировал только один).

  • Измените сценарий предварительной сборки для каждого выпуска, чтобы скопировать соответствующее содержимое файла настроек в файл build-master.

  • Измените сценарий после сборки, чтобы скопировать содержимое вторичного главного файла обратно в исходный главный файл.

Примечание. Если вы можете работать со своим поставщиком системы контроля версий в сценариях до и после сборки, вам не нужен вторичный мастер - вы можете просто проверить в предварительной сборке и отменить проверку в пост-сборке. . Однако это может вызвать проблемы в среде непрерывной интеграции, поскольку заблокированный файл потребует сбоя сборки.

Я тоже никогда этого не делал; хотя бывают случаи, когда мне хотелось, чтобы в VS был более простой способ сделать что-то подобное.

person Austin Salonen    schedule 11.02.2010

Просто некоторая дополнительная информация о файлах конфигурации на основе среды .NET без особого использования указанной выше реализации:

В Enterprise Library есть эта функция, начиная с версии 3.0: Резюме

Visual Studio 2010 также будет иметь эту функцию. Это называется преобразованием конфигурации

person Ben Dempsey    schedule 12.02.2010