Передача сообщений в рамках плагина - PullRequest
2 голосов
/ 09 сентября 2008

Прежде всего, есть немного предыстории этой проблемы, доступной в моем блоге:

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

Существует ряд различных типов плагинов, которые может обрабатывать инфраструктура (например, учетные записи, экспорт, отчетность и т. Д.). Тем не менее, я сосредоточился на одном конкретном классе плагинов, так называемых плагинах данных, так как именно этот класс вызывает у меня проблемы. У меня есть один класс подключаемых модулей данных для учетных записей, один для транзакций и т. Д.

Я на полпути к огромному ре-факторингу, который оставил мне следующую архитектуру для плагинов данных:

  • Объект подключаемого модуля данных (реализующий метаданные инициализации, установки и подключаемого модуля) [внедряет IDataPlugin<FactoryType>]
  • Объект данных (например, учетная запись) [реализует, например, IAccount]
  • Фабрика для создания экземпляров объекта данных [реализует, например, IAccountFactory]

Ранее объект данных и объект плагина были объединены в один, но это означало, что для каждой транзакции, зарегистрированной в учетной записи, необходимо было создать новый плагин транзакции, что вызвало ряд проблем. К сожалению, этот ре-факторинг нарушил мою передачу сообщений. Объект данных реализует INotifyPropertyChanged, поэтому я столкнулся с новой проблемой, и я не знаю, как ее обойти: объект плагина регистрирует события в посреднике сообщений, но это объекты данных, которые на самом деле запустить события. Это означает, что подключаемый модуль подписки в настоящее время должен подписываться на каждую созданную учетную запись, транзакцию и т. Д.! Это явно не масштабируется.

Насколько я могу сказать, на данный момент у меня есть два возможных решения:

  1. Сделать объект подключаемого модуля данных посредником для объектов данных и посредника сообщений, возможно, пакетных уведомлений об изменениях. Мне это не нравится, потому что это добавляет еще один уровень сложности к системе обмена сообщениями, который, я думаю, я смог бы обойтись.
  2. Нежелательная текущая реализация, основанная на событиях, и использование чего-то другого, более легкого в управлении (WCF в памяти?!).

Итак, я действительно спрашиваю:

  1. Как бы вы решили эту проблему?
  2. Как вы думаете, какие потенциальные решения я упустил?
  3. Мой подход даже смутно на ходу / разумный ?! : -)

Как вы можете судить по датам постов в блоге, какой-то вариант этой проблемы облагал меня налогами уже довольно давно! Таким образом, любые ответы будут высоко оценены.

Фон самого каркаса выглядит следующим образом:

Моя структура плагинов состоит из трех основных компонентов: брокера плагинов, менеджера предпочтений и брокера сообщений. Брокер плагинов делает плагин «хлеб с маслом»: обнаружение и создание плагинов. Менеджер предпочтений управляет пользовательскими предпочтениями для платформы и отдельных подключаемых модулей, например, какие подключаемые модули включены, где должны быть сохранены данные и т. Д. Связь осуществляется через публикацию / подписку, когда посредник сообщений находится в середине, собирая все опубликованные типы сообщений и управление подписками. Публикация / подписка в настоящее время осуществляется через интерфейс .NET INotifyPropertyChanged, который предоставляет одно событие под названием PropertyChanged; брокер сообщений создает список всех подключаемых модулей, реализующих INotifyPropertyChanged, и подписывает другие подключаемые модули на это событие. Цель передачи сообщений - позволить подключаемым модулям учетной записи и транзакции уведомлять подключаемые модули хранения об изменении данных, чтобы их можно было сохранить.

Ответы [ 3 ]

4 голосов
/ 09 сентября 2008

Вау! Большой вопрос! :)

Поправь меня, если я ошибаюсь. Ваше базовое решение теперь является своего рода шаблоном Observer, где объект данных (учетная запись и т. Д.) Уведомляет об изменениях в своих состояниях. Вы думаете, что проблема заключается в том, что подписывающий плагин должен регистрироваться в каждом объекте, чтобы иметь возможность обрабатывать уведомления.

Само по себе это не проблема, вы можете поместить элемент управления событиями в Модель домена , но я предлагаю вам создать Сервисный уровень и делать уведомления о событиях в этом слое. Таким образом, только один объект будет отвечать за публикацию уведомлений.

Мартин Фаулер опубликовал серию шаблонов событий в своем блоге. Проверьте это ! Очень хорошее чтение.

3 голосов
/ 09 сентября 2008

Это мое понимание вашего вопроса: у вас есть плагин-объект, которому, возможно, придется прослушивать события в x объектах данных - однако вы не хотите подписываться на событие для каждого объекта данных. Я предполагаю, что несколько плагинов могут захотеть прослушивать события в одном и том же объекте данных.

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

Это означает, что ваши плагины должны подписываться только на одно событие, но они получают событие от всех объектов данных.

С другой стороны, если только один плагин будет когда-либо слушать объект данных одновременно, почему бы просто не заставить объект данных напрямую вызывать плагин?

1 голос
/ 09 сентября 2008

Пока еще рано, но рассматривали ли вы попытку использовать MEF вместо того, чтобы бросать свои собственные?

...