sh1’s diary

プログラミング、読んだ本、資格試験、ゲームとか私を記録するところ

Prism EventAggregator を使用する方法

f:id:shikaku_sh:20211013180838p:plain:w400

この記事は、ARCTOUCH のブログ記事「How to use Prism EventAggregator for .NET app development」を個人的に雑訳したものです。

前回記事では、.NET アプリ開発に Prism EventAggregator を使用する理由、Publisher-Subscriber パターン、そして、使用するシナリオについて説明しました。今回は、具体的な使用方法をコードと共に紹介します。

環境構築 (Installation?)

必要ありません。EventAggregator は Prism.Core の一部分なので、すでに Prism を使っているプロジェクトであれば、EventAggregator の準備は OK です。

コンストラクターの注入 (inject)

EventAggregator は、IEventAggregator というインターフェースを実装しています。これを(Prism の IoC に登録された) 任意のクラスで使用するためには、コンストラクターIEventAggregatorインスタンスを要求するだけです。

public MyViewModel(IEventAggregator eventAggregator)
{
    _eventAggregator = eventAggregator;
}

Prism は ViewModel の構築時に、自動的に EventAggregatorインスタンスを受け渡しをします。他に登録や設定をする必要はありません。

イベントの作成

つぎに、送信するなにか、つまり、イベントが必要になります。イベントには2種類あります:

  • パラメーターのあるイベント
  • パラメーターのないイベント

パラメーターのないイベントを作成する場合は、通常だと新しいクラスを作成して PubSubEvent を継承します。

public class MyEvent : PubSubEvent
{
}

パラメーターのあるイベントを作成する場合は、ジェネリック型の PubSubEvent<T> を継承します。ここで、T は渡したいパラメーターの型になります。T は、プリミティブな型や複雑なオブジェクトであったりすることができます。

イベントの購読

EventAggregator とイベントの準備ができたので、今度はイベントをイベントを購読します。まず、EventAggregatorGetEvent<TEvent>() メソッドを呼び出して、イベントのインスタンスを返します。次に、イベントを処理するメソッドや Action 型を渡して、イベントの Subscribe(...) を呼び出します。

public class MySubscriberViewModel
{
    public MySubscriberViewModel(IEventAggregator eventAggregator)
    {  
        eventAggregator
        .GetEvent<MyEvent>()
        .Subscribe(HandleMyEvent);
    }

    private void HandleMyEvent()
    {
        // Do some stuff here
    }
}

パラメーターのあるイベントを処理する場合も同様です:

public class MySubscriberViewModel
{
    public MySubscriberViewModel(IEventAggregator eventAggregator)
    {
        eventAggregator
        .GetEvent<MyParameterEvent>()
        .Subscribe(HandleMyParameterEvent);
    }
    private void HandleMyEvent(MyParameter parameter)
    {
        // Do some stuff with the parameter here
    }
}

イベントの発行

イベントが処理(受け取り)されるようになったので、あとはイベントを発行するだけです。これを行うためには、再び GetEvent<TEvent>() メソッドを呼び出して、発行したいイベントのインスタンスを取得する必要があり、取得したインスタンスから、今回は Publish(...) メソッドを呼び出します。

public class MyPublisherViewModel
{
    private readonly IEventAggregator _eventAggregator;

    public MyPublisherViewModel(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
    }

    private void PublishEvent()
    {
        _eventAggregator
        .GetEvent<MyEvent>()
        .Publish();
    }
}
public class MyPublisherViewModel
{
    private readonly IEventAggregator _eventAggregator;

    public MyPublisherViewModel(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
    }

    private void PublishParameterEvent()
    {
        _eventAggregator
        .GetEvent<MyParameterEvent>()
        .Publish(new MyParameter());
    }
}

イベントの購読解除

最後に、イベントの購読を解除したいときは、Unsubscribe() メソッドを使ってイベントの購読を簡単に解除できます。

_eventAggregator
.GetEvent<MyEvent>()
.Unsubscribe(HandleMyEvent);

高度なこと (Advanced stuff)

これまで説明した内容で、95% のケースは十分にカバーできるはずです。しかし、さらに制御をしたい場合も、EventAggregator でカバーできます。Subscribe() メソッドには、オプションのパラメーターがあるので、これを使って EventAggregator の動作を構築することができます:

  • threadOption
    どのスレッドでイベントが処理されるのかを指定する列挙型オプションです。3つの値があります。
    1. PublisherThread (Default)
    2. UIThread
    3. BackgroundThread
  • keepSubscriberReferenceAlive
    デフォルトでは false に設定されているパラメーターです。EventAggregator が他に参照を持たない場合でも、サブスクライバーの参照を保持します。ガベージコレクションされることを防ぎたい場合は、このパラメーターを true に設定します。(この設定によって Xamarin.MessagingCenter と同様の動作をします)
  • filter
    サブスクライバーがイベントを受信すべきかどうかを評価する bool 値を返却するラムダ式を受け取るフィルター。(この機能は、パラメーターを持つイベントにのみ適用できます)
_eventAggregator
  .GetEvent<MyParameterEvent>()
  .Subscribe(
    HandleMyEvent,              // イベント受信時の実行メソッド
    ThreadOption.UIThread,      // UI スレッドで実行する
    true,                       // 強参照を保持する
    value => value == "valid"); // 実行メソッドはパラメーターが `valid` のときだけ実行される

このとおり、EventAggregator は簡単に使える強力なツールです。サンプルを確認したい人は、つぎのリポジトリーを確認してください。

参考