Передача сообщений во фреймворке плагинов

Во-первых, в моем блоге есть небольшая предыстория этой проблемы:

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

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

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

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

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

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

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

Думаю, я действительно спрашиваю:

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

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

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

My plug-in framework consists of three main components: a plug-in broker, a preferences manager and a message broker. The plug-in broker does the bread-and-butter plug-in stuff: discovering and creating plug-ins. The preferences manager manages user preferences for the framework and individual plug-ins, such as which plug-ins are enabled, where data should be saved, etc. Communication is via publish/subscribe, with the message broker sitting in the middle, gathering all published message types and managing subscriptions. The publish/subscribe is currently implemented via the .NET INotifyPropertyChanged interface, which provides one event called PropertyChanged; the message broker builds a list of all plug-ins implementing INotifyPropertyChanged and subscribes other plug-ins this event. The purpose of the message passing is to allow the account and transaction plug-ins to notify the storage plug-ins that data has changed so that it may be saved.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 111
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ух ты! Большой вопрос! :)

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

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

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

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

Ответ принят как подходящий

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

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

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

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

Другие вопросы по теме