Способы составления конфигурации для составных приложений (например, PRISM, MEF)
Рамки, такие как PRISM и MEF, позволяют легко создавать сложные приложения из множества составных компонентов. Одним из распространенных примеров этого является архитектура подключаемого модуля, в которой оболочка приложения может быть рефинансирована с помощью подключаемых компонентов пользовательского интерфейса (например, путем удаления библиотек DLL в каталог Plug-ins
).
Это все хорошо и хорошо, но поскольку Vaccano замечен в Может ли Prism быть модульным при вызове веб-сервисов? существуют обстоятельства, при которых каждому отдельному подключаемому модулю требуется свой собственный набор конфигурации - типичные примеры привязок WCF, но есть много других сценариев (протоколирование, соединения с базой данных и т.д.) с аналогичными потребностями.
Итак, как я вижу, у нас есть следующие опции:
- Вся конфигурация переходит в
App.config
приложения оболочки (что, как упоминает Ваккано, нарушает все преимущества инкапсуляции и развертывания этой модели) или
- Каждый подключаемый модуль использует специальный механизм для конфигурации (например, встроенный ресурс), а затем использует его для динамической настройки службы WCF, например (которая в лучшем случае беспорядочна и требует много времени, а в худшем случае может быть невозможна )
Ни один из этих вариантов не идеален, но это обходные пути. Тем не менее, идеальная ситуация для каждой подключаемой DLL-версии должна иметь либо автономную конфигурацию (например, встроенный файл ресурсов), либо файл Xxx.dll.config
, и каждый из этих фрагментов XML-конфигурации объединяется в конфигурацию App.config
приложение оболочки динамически во время выполнения. Это напоминает способ объединения файлов Machine.config
и App.config
.
Таким образом, мой вопрос: кто-нибудь сталкивается с любыми существующими инфраструктурами или методами, которые могут быть использованы для обеспечения возможности динамического объединения составных конфигурационных файлов в конфигурацию контейнера в процессе? Я удивлен, не увидев это как часть PRISM или MEF, и поэтому немного опасаюсь опубликовать этот вопрос, если я пропустил что-то очевидное - если да, просто спокойно разместите соответствующую ссылку:)
Ответы
Ответ 1
Мы столкнулись с одной и той же проблемой. Я тоже не нашел решения.
Здесь две вещи, которые я видел, люди делают (или мы сделали):
Регистрация конечной точки вручную
Создайте реестр служб приложений, в котором говорится, как сделать ChannelFactory с T. Каждый модуль может внести свой вклад в это в Имодуле Имоделирования, вызвав RegisterService<T>
, и все подчиненные представления этого Модуля могут получить от него свои Фактории Каналов:
public interface IServiceRegistry
{
void RegisterService<T>(ServiceEndpoint ep);
ChannelFactory<T> GetService<T>();
}
Вместо возврата ChannelFactory<T>
здесь вы можете просто вернуться T
, конечно (caveat emptor). View/ViewModels просто попросят IServiceRegistry как зависимость и захватить их прокси-сервисы таким образом. Это также обеспечивает удобное место для изоляции при написании модульных тестов.
Встроенная конфигурация
Система соглашений, грубо выполняющая то же, что и выше, но на основе конфигурации, встроенной в DLL (как вы предполагали), и использования именованных конфигураций. Вы бы потребляли это так же, как описано выше, но это был бы немного другой опыт. Мы используем соглашение "Endpoints.config", встроенное в нашу DLL, и читаем его.
public interface IServiceChannelFactoryFactory //I'm terrible at naming
{
//This is much like the generated concrete class when you use "Add Service Reference"
//Except there is no method with an empty parameter
ChannelFactory<T> GetService<T>(string endpointName);
}
Наш "Endpoints.config" имеет несколько конечных точек на одно конечное имя с добавленными атрибутами, которые делают эту конечную точку уникальной для среды (DEV, QA, Staging, Production). Я не знаю, беспокоит ли это вас, но это было удобное место для размещения такого рода конфигов.
Оба работают. Удивительно, что я не видел больше людей об этом. Большой вопрос.
Ответ 2
Проект по композитным услугам из шаблонов и практик (та же команда, которая принесла вам Prism) предоставляет шаблоны проектирования и реализации для обнаружения сервисов, состава и интеграции.
Что касается слияния динамических конфигураций, взгляните на реализацию сложных конфигурационных сценариев, которые мы имеем в Enterprise Library 5.0. Он не является общим и ориентирован только на конфигурацию Enterprise Library, но вы все равно можете изучить исходный код.
Ответ 3
Для приложения Windows/WPF вы можете это сделать, создав поставщика настраиваемых параметров - это класс, который вы создаете, который подключается к системе конфигурации .net.
Теоретически, вы можете поместить свои настройки в файлы конфигурации, специфичные для модуля. Вы бы создали поставщика настроек, который знает, как искать эти файлы, зависящие от модуля, во время выполнения и предоставляет настройки. Поскольку это сидит "ниже", потребители конфигурации в стеке, WCF или другой технологии не должны знать ничего особенного, чтобы использовать его. Единственным недостатком является то, что он не поддерживается в Silverlight.
Здесь ссылка на статью проекта кода, в которой она реализована: http://www.codeproject.com/KB/vb/CustomSettingsProvider.aspx
Вот ссылка на документацию MSDN: http://msdn.microsoft.com/en-us/library/system.configuration.settingsprovider.aspx