1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Prism コードサンプル学習:14-UsingEventAggregator

Posted at

Prism コードサンプル学習:14-UsingEventAggregator

はじめに

以下の記事の続きです。
https://qiita.com/mngreen/items/787f8f92e2da3c787770

14-UsingEventAggregator

本サンプルは、互いに依存していないモジュール間でメッセージを送受し、連携して動作することを確認するサンプルとなっています。

UsingEventAggregator.Coreではモジュール間で共通して利用されるMessageSentEventクラスを定義しています。

using Prism.Events;

namespace UsingEventAggregator.Core
{
    public class MessageSentEvent : PubSubEvent<string>
    {
    }
}

PubSubEvent<T>EventBaseクラスを継承していて、内部的には購読者をコレクションとして保持していることがわかります。

Subscribeの実処理では、まずはじめにActionReferenceを生成しています。渡されたアクションからそのアクションの持ち主であるインスタンスを特定しています。
その後、それぞれのオプションによって生成されるインスタンスが異なりますが、基本的に利用されそうなEventSubscriptionクラスでは、必要に応じてアクションを実行するか否かを決める処理(GetExecutionStrategy)が重要そうでした。
上記のメソッドがどこで利用されるかというと、EventBaseクラスのInternalPublishメソッド内にあるPruneAndReturnStrategiesメソッドです。この中で実行対象が抽出されます。

上記のイベントをModuleAは発行、ModuleBは購読しているのが以下のコードです。

namespace ModuleA.ViewModels
{
    public class MessageViewModel : BindableBase
    {
        IEventAggregator _ea;

        private string _message = "Message to Send";
        public string Message
        {
            get { return _message; }
            set { SetProperty(ref _message, value); }
        }

        public DelegateCommand SendMessageCommand { get; private set; }

        public MessageViewModel(IEventAggregator ea)
        {
            _ea = ea;
            SendMessageCommand = new DelegateCommand(SendMessage);
        }

        private void SendMessage()
        {
            // イベントアグリゲーターからイベントを取得してメッセージを発行する
            _ea.GetEvent<MessageSentEvent>().Publish(Message);
        }
    }
}

namespace ModuleB.ViewModels
{
    public class MessageListViewModel : BindableBase
    {
        IEventAggregator _ea;

        private ObservableCollection<string> _messages;
        public ObservableCollection<string> Messages
        {
            get { return _messages; }
            set { SetProperty(ref _messages, value); }
        }

        public MessageListViewModel(IEventAggregator ea)
        {
            _ea = ea;
            Messages = new ObservableCollection<string>();

            // イベントアグリゲーターを経由して、イベントを購読している
            _ea.GetEvent<MessageSentEvent>().Subscribe(MessageReceived);
        }

        private void MessageReceived(string message)
        {
            Messages.Add(message);
        }
    }
}

EventAggregatorでは型をキー、イベントをバリューとするディクショナリーを保持しており、要求に応じてイベントを返します。
EventAggregator自体は全体で46行ほどしかなく、GetEvent<TEventType>メソッドを公開しているのみで非常にシンプルな作りになっています。

おわりに

今回はEventAggregatorの使い方と、そのライブラリ内部の実装を読んでみました。
EventAggregatorを利用することで、結合が疎であるモジュール間でもうまく連携できそうです。
また、APIをシンプルに保つための工夫として、Actionの持ち主であるインスタンスを引数にわたすのではなく、Actionからインスタンスを探し出す方法を採用しているのは、勉強になりました。
次回、15-FilteringEventsについて見ていこうと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?