Способы составления конфигурации для составных приложений (например, 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