Во-первых, в моем блоге есть небольшая предыстория этой проблемы:
Я знаю, что описания не очень ясны, поэтому я постараюсь как можно лучше резюмировать то, что я пытаюсь сделать здесь. Приложение представляет собой программу личных финансов. Дальнейшая информация о самом фреймворке доступна в конце этого поста.
Фреймворк может обрабатывать несколько различных типов подключаемых модулей (например, учетные записи, экспорт, отчетность и т. д.). Однако я сосредотачиваюсь на одном конкретном классе подключаемых модулей, так называемых подключаемых модулях данных, поскольку именно этот класс вызывает у меня проблемы. У меня есть один класс подключаемых модулей данных для учетных записей, один для транзакций и т. д.
Я на полпути через обширный рефакторинг, который оставил мне следующую архитектуру для подключаемых модулей данных:
IDataPlugin<FactoryType>]IAccount]IAccountFactory]Ранее объект данных и объект подключаемого модуля были объединены в один, но это означало, что для каждой транзакции, записанной в учетной записи, приходилось создавать экземпляр нового подключаемого модуля транзакции, что вызывало ряд проблем. К сожалению, этот рефакторинг нарушил мою передачу сообщений. Объект данных реализует INotifyPropertyChanged, поэтому я столкнулся с новой проблемой, и я не знаю, как ее обойти: объект подключаемого модуля регистрирует события в брокере сообщений, но на самом деле срабатывают объекты данных. события. Это означает, что подключаемый модуль подписки в настоящее время должен подписаться на каждую созданную учетную запись, транзакцию и т. д.! Это явно не масштабируемо.
Насколько я могу судить, на данный момент у меня есть два возможных решения:
Думаю, я действительно спрашиваю:
Как вы сможете судить по датам публикаций в блоге, какой-то вариант этой проблемы уже давно меня обременяет! Таким образом, мы будем очень благодарны за любые ответы.
Предыстория самого фреймворка выглядит следующим образом:
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
INotifyPropertyChangedinterface, which provides one event calledPropertyChanged; the message broker builds a list of all plug-ins implementingINotifyPropertyChangedand 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.





Ух ты! Большой вопрос! :)
Поправьте меня если я ошибаюсь. Теперь ваше базовое решение представляет собой своего рода шаблон наблюдателя, в котором объект данных (учетная запись и т. д.) Уведомляет об изменениях в своих состояниях. Вы думаете, что проблема в том, что подключаемый модуль для подписки должен регистрироваться в каждом объекте, чтобы иметь возможность обрабатывать уведомления.
Само по себе это не проблема, вы можете поместить элемент управления событиями в Модель домена, но я предлагаю вам создать Уровень обслуживания и делать уведомления о событиях на этом уровне. Таким образом, только один объект будет отвечать за публикацию уведомлений.
Мартин Фаулер опубликовал в своем блоге серию шаблонов событий. Проверить это! Очень хорошее чтение.
Еще рано, но думали ли вы о том, чтобы попробовать использовать MEF вместо собственного?
Это мое понимание вашего вопроса: у вас есть объект плагина, который, возможно, должен будет прослушивать события на x объектах данных - однако вы не хотите подписываться на событие для каждого объекта данных. Я предполагаю, что несколько плагинов могут захотеть прослушивать события одного и того же объекта данных.
Вы можете создать объект типа сеанса. Каждый плагин прослушивает события в объекте сеанса. Объект данных больше не вызывает событие - он вызывает объект сеанса, чтобы инициировать событие (одним из параметров должен быть объект данных, вызывающий событие).
Это означает, что ваши плагины должны подписаться только на одно событие, но они получают событие от всех объектов данных.
С другой стороны, если только один плагин будет когда-либо слушать объект данных за раз, почему бы просто не сделать так, чтобы объект данных не вызывал плагин напрямую?