Во-первых, в моем блоге есть небольшая предыстория этой проблемы:
- http://www.codebork.com/coding/2008/06/25/message-passing-a-plug-framework.html
- http://www.codebork.com/coding/2008/07/31/message-passing-2.html
Я знаю, что описания не очень ясны, поэтому я попытаюсь обобщить то, что я пытаюсь сделать, насколько это возможно. Приложение представляет собой программу личных финансов. Дополнительную информацию о самом фреймворке можно найти в конце этого поста.
Существует несколько различных типов подключаемых модулей, которые может обрабатывать платформа (например, учетные записи, экспорт, отчеты и т. д.). Однако я сосредоточусь на одном конкретном классе подключаемых модулей, так называемых подключаемых модулях данных, поскольку именно этот класс вызывает у меня проблемы. У меня есть один класс подключаемого модуля данных для учетных записей, один для транзакций и т. д.
Я нахожусь на полпути через обширный рефакторинг, который оставил мне следующую архитектуру для подключаемых модулей данных:
- Объект подключаемого модуля данных (реализующий инициализацию, установку и метаданные подключаемого модуля) [реализует
IDataPlugin<FactoryType>
] - Объект данных (например, учетная запись) [реализует, например,
IAccount
] - Фабрика для создания экземпляров объекта данных [реализует, например,
IAccountFactory
]
Ранее объект данных и объект плагина были объединены в один, но это означало, что для каждой транзакции, зарегистрированной в учетной записи, нужно было создавать новый плагин транзакции, что вызывало ряд проблем. К сожалению, этот рефакторинг нарушил передачу моего сообщения. Объект данных реализует INotifyPropertyChanged
, и поэтому я столкнулся с новой проблемой, которую я не знаю, как обойти: объект подключаемого модуля регистрирует события с помощью брокера сообщений, но на самом деле срабатывают объекты данных. события. Это означает, что подключаемый модуль подписки в настоящее время должен подписываться на каждую созданную учетную запись, транзакцию и т. д.! Это явно не масштабируется.
Насколько я могу судить на данный момент, у меня есть два возможных решения:
- Сделайте объект подключаемого модуля данных посредником между объектами данных и брокером сообщений, возможно, группируя уведомления об изменениях. Мне это не нравится, потому что это добавляет еще один уровень сложности в систему обмена сообщениями, без которого, как мне кажется, я мог бы обойтись.
- Отбросьте текущую реализацию на основе событий и используйте что-то другое, более легко управляемое (WCF в памяти?!).
Так что, наверное, я действительно спрашиваю:
- Как бы вы решили эту проблему?
- Как вы думаете, какие потенциальные решения я упустил из виду?
- Является ли мой подход хотя бы смутно правильным/разумным?! :-)
Как вы можете судить по датам сообщений в блоге, какой-то вариант этой проблемы мучает меня уже довольно давно! Таким образом, любые ответы будут очень признательны.
Предыстория самого фреймворка такова:
Моя структура плагинов состоит из трех основных компонентов: плагин-брокер, менеджер настроек и брокер сообщений. Брокер подключаемых модулей выполняет основные функции подключаемых модулей: обнаруживает и создает подключаемые модули. Диспетчер настроек управляет пользовательскими настройками для платформы и отдельных плагинов, например, какие плагины включены, где должны быть сохранены данные и т. д. Связь осуществляется через публикацию/подписку, а брокер сообщений сидит посередине и собирает все опубликованные типы сообщений и управление подписками. Публикация/подписка в настоящее время реализуется через интерфейс .NET
INotifyPropertyChanged
, который предоставляет одно событие с именемPropertyChanged
; брокер сообщений создает список всех подключаемых модулей, реализующихINotifyPropertyChanged
, и подписывает другие подключаемые модули на это событие. Цель передачи сообщений — позволить подключаемым модулям учетных записей и транзакций уведомить подключаемые модули хранилища об изменении данных, чтобы их можно было сохранить.