Приложение B: включая внешние файлы конфигурации
Несмотря на все величие, которое можно найти в функциях конфигурации .NET 2.0, есть один недостаток. При работе над одним проектом в нескольких средах управление конфигурацией может стать кошмаром. Процесс управления несколькими версиями файла конфигурации для нескольких сред - т.е. разработки, тестирования, подготовки и производства - в моей текущей работе включает ручное сравнение файлов .config
при каждом развертывании изменений в той или иной среде с помощью руководства процесс слияния. Я потратил месяцы, пытаясь найти лучший путь, и в конце концов нашел его. Введите одну из тех самых «недокументированных» - или в данном случае просто плохо документированных - функций, которыми так славится Microsoft: configSource
. Я столкнулся с этим маленьким драгоценным камнем, когда копался в исходном коде конфигурации .NET 2.0 с помощью Reflector, замечательного маленького инструмента.
Каждому разделу конфигурации, когда он анализируется и загружается классами конфигурации .NET, назначается объект SectionInformation
. Объект SectionInformation
содержит метаинформацию о разделе конфигурации и позволяет некоторым образом управлять тем, как разделы перекрывают друг друга при определении в дочернем файле конфигурации (ASP.NET). Сейчас мы будем игнорировать большинство из того, что может предложить SectionInformation, за исключением свойства ConfigSource
. Добавив атрибут configSource
к корневому элементу любого ConfigurationSection
, вы можете указать альтернативный внешний источник, из которого будут загружаться параметры конфигурации.
<!-- SomeProgram.exe.config -->
<configuration>
<connectionStrings configSource="externalConfig/connectionStrings.config"/>
</configuration>
<!-- externalConfig/connectionStrings.config -->
<connectionStrings>
<add name="conn" connectionString="blahblah" />
</connectionStrings>
В приведенном выше файле конфигурации раздел <connectionStrings>
был получен из файла с именем externalConfig/connectionStrings.config
. Все строки подключения приложения будут загружены из указанного файла. Теперь, когда строки подключения загружены из внешнего ресурса, создать файл connectionStrings.config
в каждой среде в одном и том же относительном расположении довольно просто. Следовательно, externalConfig/
часть пути connectionStrings.config
. Прелесть здесь в том, что мы можем правильно определить строки подключения для каждой среды. Нам не нужно беспокоиться о случайном переопределении этих параметров во время развертывания, когда файл конфигурации был либо неправильно объединен, либо не объединен вообще. Это может быть огромным благом при развертывании изменений в приложении в производственной среде, где важно наличие правильных строк подключения к базе данных. Недостаток использования атрибута configSource
заключается в том, что он требует, чтобы все параметры конфигурации были помещены во внешний файл. Наследование или переопределение невозможно, что в некоторых случаях делает его бесполезным. Все внешние файлы конфигурации, используемые с атрибутом configSource
, также должны находиться в относительном дочернем пути к основному файлу .config
. Я считаю, что это связано с проблемами безопасности при хранении файла в относительном родительском пути в веб-среде.
Еще кое-что следует отметить, что в разделе <appSettings>
есть лучшая альтернатива использованию configSource
, называемая file. Если вы используете атрибут файла вместо configSource с разделом <appSettings>
, вы можете определить настройки как в корневом .config
файле, так и в указанном файле. Настройки из корневого файла .config
также могут быть переопределены в указанном файле, просто добавив что-то с тем же ключом. К сожалению, атрибут file доступен только в разделе <appSettings>
и не встроен в инфраструктуру конфигурации. Можно реализовать аналогичный атрибут в ваших собственных разделах конфигурации. Это будет обсуждаться в следующих выпусках расширенных разделов конфигурации после нескольких обязательных выпусков;).