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

.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 везде, чтобы определить, какой класс использовать, поскольку они не являются производными от общего класса .

Ответы [ 6 ]

2 голосов
/ 12 февраля 2010

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

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

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

2 голосов
/ 12 февраля 2010

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

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

1 голос
/ 13 февраля 2010

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

1 голос
/ 12 февраля 2010

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

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

0 голосов
/ 12 февраля 2010

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

Корпоративная библиотека имеет эту функцию начиная с версии 3.0: Краткое описание

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

0 голосов
/ 11 февраля 2010

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

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

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

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

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

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

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

...