Event Aggregator, интересное ограничение дизайна - PullRequest
1 голос
/ 04 октября 2011

Очень интересная проблема (или ограничение дизайна), с которой я столкнулся в последнее время.

Я разрабатывал приложение, построенное с использованием WPF / Prism.

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

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

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

Я думаю, эта проблема будет и с обычными событиями, и это фактически делаетпредназначенные для уведомления всех подписчиков.

мы поставили проверки, чтобы определить, какая виртуальная машина инициирует операцию только для того, чтобы VM shd выполняла код после получения уведомления.

Мой вопрос: что должно быть правильным?дизайн в этом очень редком сценарии?

Ответы [ 2 ]

2 голосов
/ 04 октября 2011

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

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

 Guid referenceGuid = Guid.NewGuid();

//Subscribe to the futures events which are being published by the background service (filter per referenceGuid).
_eventAggregator.GetEvent<RetrieveMetricsResponseEvent>().Subscribe(ProcessUpdates, ThreadOption.BackgroundThread, true, response => response.ReferenceId == referenceGuid);



// Send the request to the background service
_eventAggregator.GetEvent<RetrieveMetricsRequestEvent>().Publish(new WrappedRetrieveMetricsRequest { MetricSourceID = configuration.StrategyInstanceCode, Identifier = configuration.SourceValueFieldName, ReferenceId = referenceGuid });
1 голос
/ 04 октября 2011

Обычно я присоединяю параметр к EventMessage, который определяет, какая ViewModel должна обрабатывать событие.Если это значение может быть нулевым (то есть любая виртуальная машина может его обработать), я часто добавляю свойство Handled к EventMessage и первый ViewModel, который обрабатывает наборы событий eventParams.Handled = true

Например, для публикациисобытие для той же виртуальной машины, я бы использовал следующий синтаксис:

// Publish for specific ViewModel
eventAggregator.GetEvent<MyMessage>().Publish(
    new MyEventArgs { SpecifiedViewModel = this });

// Publish for any ViewModel
eventAggregator.GetEvent<MyMessage>().Publish(
    new MyEventArgs());

Чтобы обработать событие, которое должно обрабатываться только одной ViewModel, код может выглядеть следующим образом:

void HandleEvent(MyEventArgs e)
{
    if ((SpecifiedViewModel == null && !(e.Handled))
     || (SpecifiedViewModel == this))
    {
        // Handle Event
        e.Handled == true;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...