パブリッシュ/サブスクライブ パターンは、パブリッシャーがサブスクライバーと呼ばれる受信者に関する知識を持たずにメッセージを送信するメッセージング パターンです。 同様に、サブスクライバーは発行元の知識がなくても、特定のメッセージをリッスンします。
.NET のイベントは、パブリッシュ/サブスクライブ パターンを実装し、疎結合が必要ない場合 (コントロールやそれを含むページなど) のコンポーネント間の通信レイヤーの最も単純で簡単なアプローチです。 ただし、パブリッシャーとサブスクライバーの有効期間は、相互にオブジェクト参照によって結合され、サブスクライバーの種類にはパブリッシャーの種類への参照が必要です。 これにより、メモリ管理の問題が発生する可能性があります。特に、静的オブジェクトまたは有効期間の長いオブジェクトのイベントをサブスクライブする有効期間の短いオブジェクトがある場合です。 イベント ハンドラーが削除されない場合、サブスクライバーはパブリッシャー内の参照によって生き続け、これによりサブスクライバーのガベージ コレクションが妨げられたり、遅延したりします。
.NET マルチプラットフォーム アプリ UI (.NET MAUI) MessagingCenter クラスは、パブリッシュ/サブスクライブ パターンを実装します。これにより、オブジェクトと型の参照によるリンクに不便なコンポーネント間のメッセージ ベースの通信が可能になります。 このメカニズムにより、パブリッシャーとサブスクライバーは相互に参照を持たずに通信でき、それらの間の依存関係を減らすことができます。
大事な
MessagingCenter は非推奨となりました。CommunityToolkit.Mvvm NuGet パッケージの WeakReferenceMessenger
に置き換えることをお勧めします。 詳細については、「Messenger」を参照してください。
MessagingCenter クラスは、マルチキャストのパブリッシュ/サブスクライブ機能を提供します。 つまり、1 つのメッセージを発行するパブリッシャーが複数存在する可能性があり、同じメッセージをリッスンしているサブスクライバーが複数存在する可能性があります。
パブリッシャーは MessagingCenter.Send
メソッドを使用してメッセージを送信し、サブスクライバーは MessagingCenter.Subscribe
メソッドを使用してメッセージをリッスンします。 さらに、サブスクライバーは、必要に応じて、MessagingCenter.Unsubscribe
メソッドを使用して、メッセージ サブスクリプションのサブスクライブを解除することもできます。
大事な
内部的には、MessagingCenter クラスは弱参照を使用します。 つまり、オブジェクトは生存し続けず、ガベージコレクションされるようになります。 そのため、クラスがメッセージを受信したくない場合のみ、メッセージの登録を解除する必要があります。
メッセージを発行する
MessagingCenter メッセージは文字列です。 パブリッシャーは、MessagingCenter.Send
オーバーロードのいずれかを使用してサブスクライバーにメッセージを通知します。 次のコード例では、Hi
メッセージを発行します。
MessagingCenter.Send<MainPage>(this, "Hi");
この例では、Send
メソッドは送信者を表すジェネリック引数を指定します。 メッセージを受信するには、サブスクライバーがその送信者からのメッセージをリッスンしていることを示す同じジェネリック引数も指定する必要があります。 さらに、この例では、次の 2 つのメソッド引数を指定します。
- 最初の引数は、送信側インスタンスを指定します。
- 2 番目の引数はメッセージを指定します。
ペイロード データは、次のメッセージと共に送信することもできます。
MessagingCenter.Send<MainPage, string>(this, "Hi", "John");
この例では、Send
メソッドは 2 つのジェネリック引数を指定します。 1 つ目はメッセージを送信する型、2 つ目は送信されるペイロード データの型です。 メッセージを受信するには、サブスクライバーも同じジェネリック引数を指定する必要があります。 これにより、メッセージ ID を共有し、異なるペイロード データ型を送信する複数のメッセージを、異なるサブスクライバーが受信できるようになります。 さらに、この例では、サブスクライバーに送信されるペイロード データを表す 3 番目のメソッド引数を指定します。 この場合、ペイロード データは string
です。
Send
メソッドは、ファイア アンド フォーゲット アプローチを使用して、メッセージとペイロード データを発行します。 そのため、メッセージを受信するサブスクライバーが登録されていない場合でも、メッセージが送信されます。 この状況では、送信されたメッセージは無視されます。
メッセージを購読する
サブスクライバーは、MessagingCenter.Subscribe
オーバーロードのいずれかを使用してメッセージを受信するように登録できます。 次のコード例は、この例を示しています。
MessagingCenter.Subscribe<MainPage> (this, "Hi", (sender) =>
{
// Do something whenever the "Hi" message is received
});
この例では、Subscribe
メソッドは、MainPage
型によって送信される Hi
メッセージを this
オブジェクトにサブスクライブし、メッセージの受信に応じてコールバックデリゲートを実行します。 ラムダ式として指定されたコールバック デリゲートは、UI を更新したり、データを保存したり、他の操作をトリガーしたりするコードである可能性があります。
手記
サブスクライバーは、パブリッシュされたメッセージのすべてのインスタンスを処理する必要がない場合があります。これは、Subscribe
メソッドで指定されたジェネリック型引数によって制御できます。
次の例は、ペイロード データを含むメッセージをサブスクライブする方法を示しています。
MessagingCenter.Subscribe<MainPage, string>(this, "Hi", async (sender, arg) =>
{
await DisplayAlert("Message received", "arg=" + arg, "OK");
});
この例では、Subscribe
メソッドは、ペイロード データが string
である MainPage
型によって送信される Hi
メッセージをサブスクライブします。 このようなメッセージの受信に応答してコールバック デリゲートが実行され、アラートにペイロード データが表示されます。
大事な
Subscribe
メソッドによって実行されるデリゲートは、Send
メソッドを使用してメッセージを発行するのと同じスレッドで実行されます。
メッセージの登録を解除する
サブスクライバーは、受信しなくなったメッセージのサブスクライブを解除できます。 これは、MessagingCenter.Unsubscribe
オーバーロードのいずれかで実現されます。
MessagingCenter.Unsubscribe<MainPage>(this, "Hi");
この例では、Unsubscribe
メソッドは、MainPage
型によって送信された Hi
メッセージから this
オブジェクトの登録を解除します。
ペイロード データを含むメッセージは、2 つのジェネリック引数を指定する Unsubscribe
オーバーロードの使用をサブスクライブ解除する必要があります。
MessagingCenter.Unsubscribe<MainPage, string>(this, "Hi");
この例では、Unsubscribe
メソッドは、ペイロード データが string
である MainPage
型によって送信された Hi
メッセージから this
オブジェクトの登録を解除します。
.NET MAUI