Home > C# > Toolkit > UIパターン > Prism > Prismドキュメント > Prism 6

WPFのためのPrism Libraryを使用して、疎く結合したコンポーネントの間で情報をやりとりする

新規作成日 2017-11-24
最終更新日

原文「Communicating Between Loosely Coupled Components Using the Prism Library for WPF

大規模で複雑なWPFアプリケーションを構築するとき、一般的なアプローチは、分離したモジュールアセンブリに機能を分割することです。また、それは、これらのモジュールの間での、デリゲート・コマンド、領域コンテキスト、共有されたサービスの利用、そして、イベント・アグリゲータを通して、達成されることができる、静的参照の使用を最小限にすることが、望ましいです。これは、モジュールが、独立して開発、検証、配布、更新できます。そして、それは、疎く結合した通信を強制します。このトピックは、デリゲート・コマンドとルーティング・コマンドを使用する時、そして、イベント・アグリゲータと.NET フレームワーク・イベントを使用するとき、ガイダンスを提供します。

モジュール間の情報をやりとりする時、あなたが、最良の決定をすることができるように、あなたの個々のシナリオの中で使用するための、アプローチの違いを知っていることは、重要です。Prism Libraryは、次の通信アプローチを提供します。:

  • ソリューション・コマンド ユーザーとの対話処理から、即時のアクションが予想されるとき、使用します。
  • 領域コンテキスト。 ホスト領域内のホストとViewの間で、コンテキスト情報を提供するために、これを使用します。このアプローチは、DataContextとやや類似していますが、それは、それに依存していません。
  • 共有サービス 呼び出し側は、メッセージの受け取り側で、イベントを呼び出すサービス上で、メソッドを呼び出すことができます。先行するものが、どれも適用できない場合、これを使用します。
  • イベント集約。 View Model、プレゼンターやコントローラ間の通信のための直接、動作-反応の期待がない場合、

ソリューション・コマンド

Solution Commanding

あなたが、(たとえば、ボタンやメニュー項目の)コマンドの呼び出し元をクリックするような、ユーザー・ジェスチャーに対応する必要がある場合、 そして、あなたが、ビジネス・ロジックを基づいて、有効するために、呼び出し元を望む場合、コマンドを使用します。

Windows Presentation Foundation (WPF)は、キーボードフォーカスを持っているビジュアル・ツリーの現在の項目に、関連付けられるコマンド・ハンドラで、メニュー項目とボタンのような、コマンドの呼び出し元を結合するのに役に立つRoutedCommandを提供します。

しかしながら、複合的な筋書きで、コマンド・ハンドラは、多くの場合、ビジュアル・ツリーで、関連するどんな要素も持っていないか、フォーカスされた要素ではなく、ViewModelです。この筋書きに対応するために、Prism Libraryは、コマンドが実行されるとき、あなたが、デリゲート・メソッドを呼び出すことができるDelegateCommandを提供します。そして、CompositeCommandは、あなたが、複数のcommands**.**を結合することができます。これらのコマンドは、ビジュアル・ツリー上に、そして、その下に、コマンド実行と処理を割り振りふる組み込みのRoutedCommandとは異なります。これは、あなたが、ビジュアル・ツリーのこの場所で、コマンドを起動し、そして、それを高いレベルで操作できます。

CompositeCommandは、呼び出し元に結合することができる、ICommandの実装です。CompositeCommandsは、いくつかの子のコマンドに結合されることができます。;CompositeCommandが、呼び出されるとき、子のコマンドもまた、呼び出されます。

CompositeCommandsは、有効化をサポートしています。CompositeCommandsは、その接続されているコマンドの各々のCanExecuteChangedイベントに耳を傾けます。それは、続いて、呼び出し元に知らせるこのイベントを起動します。呼び出し元は、CompositeCommand上で、CanExecuteを呼び出すことによって、このイベントに反応します。CompositeCommandは、続いて、各々の子のコマンド上で、CanExecuteを呼び出すことによって、あらためて、すべてのその子のコマンドの意見を尋ねます。CanExecuteへのどんな呼び出しも、falseを返すとき、CompositeCommandは、falseを返し、このように、呼び出し元を無効にします。

これは、どのように、あなたを、モジュールを横断する通信で支援しますか?Prism Libraryに基づいたアプリケーションは、Save、Save AllやCancelのような、モジュールを横断する意味を持つ、シェル内で定義されている、広域のCompositeCommandsを持ているかもしれません。モジュールは、続いて、これらのグローバルコマンドで、それらのローカル・コマンドを登録することができます。そして、それらの実行に関与しています。

備考: DelegateCommandとCompositeCommandは、Prism.Core Nugetパッケージに配置されるPrism.Commands名前空間で見つかります。

WPFのルーティング・イベントとルーティング・コマンドについて

About WPF Routed Events and Routed Commands

ルーティングイベントは、イベントを直接購読したオブジェクトだけに知らせる代わりに、要素ツリー内の複数のリスナー上に、ハンドラを呼び出すことができる一種のイベントです。WPFのルーティング・コマンドは、ビジュアル・ツリー内のUI要素によって、コマンド・メッセージを伝えます。しかし、ツリーの外側の要素は、これらのメッセージを受け取りません。なぜなら、それらは、フォーカスされた要素や明示的な状態の対象とする要素だけで、上昇したり、下降したりします。イベントのためのイベント・データは、ルート内の各々の要素に永続化されるため、ルーティングイベントは、要素ツリーを介して、情報をやりとりするために使用することができます。1つの要素は、イベント・データで、何かを変更することができます。そして、その変更は、ルート内で、次の要素が利用できるようになります。

その結果、あなたは、次のシナリオの中の、WPFルーティングイベントを使用する必要があります。:共通ルートに共通のハンドラを定義したり、独自のカスタムコントロールクラスを定義します。

デリゲート・コマンドを作成する

Creating a Delegate Command

デリゲート・コマンドを作成するために、あなたのViewModelのコンストラクタで、DelegateCommand領域をインスタンス化します。そして、その次に、ICommandプロパティとして、それを公開します。

// ArticleViewModel.cs
public class ArticleViewModel : BindableBase
{
    private readonly ICommand showArticleListCommand;

    public ArticleViewModel(INewsFeedService newsFeedService,
                            IRegionManager regionManager,
                            IEventAggregator eventAggregator)
    {
        this.showArticleListCommand = new DelegateCommand(this.ShowArticleList);
    }

    public ICommand ShowArticleListCommand
    {
        get { return this.showArticleListCommand; }
    }
}

複合コマンドを作成する

Creating a Composite Command

複合コマンドを作成するために、コンストラクタ内で、CompositeCommand領域をインスタンス化します。それに、コマンドを追加します。そして、その次に、ICommandプロパティとして、それを公開します。

public class MyViewModel : BindableBase
{
    private readonly CompositeCommand saveAllCommand;

    public ArticleViewModel(INewsFeedService newsFeedService,
                            IRegionManager regionManager,
                            IEventAggregator eventAggregator)
    {
        this.saveAllCommand = new CompositeCommand();
        this.saveAllCommand.RegisterCommand(new SaveProductsCommand());
        this.saveAllCommand.RegisterCommand(new SaveOrdersCommand());
    }

    public ICommand SaveAllCommand
    {
        get { return this.saveAllCommand; }
    }
}

グローバルに利用できるコマンドを作成する

Making a Command Globally Available

通常、グローバルに利用できるコマンドを作成するために、DelegateCommand、あるいは、CompositeCommandのインスタンスを作成し、静的クラスによって公開します。

public static class GlobalCommands
{
    public static CompositeCommand MyCompositeCommand = new CompositeCommand();
}

あなたのモジュールで、グローバルに利用できるコマンドに、子のコマンドを関連付けます。

GlobalCommands.MyCompositeCommand.RegisterCommand(command1);
GlobalCommands.MyCompositeCommand.RegisterCommand(command2);

備考: あなたのコードのテスト容易性を向上させるために、あなたは、グローバルに利用できるコマンドを呼び出すために、プロキシ・クラスを使用する、そして、あなたのテスト内のプロキシ・クラスのモックを作成することができます。

グローバルに利用できるコマンドに結合する

Binding to a Globally Available Command

次のコード例は、WPFのボタンをコマンドに、どのように、結合するかを示します。

<Button Name="MyCompositeCommandButton" Command="{x:Static local:GlobalCommands.MyCompositeCommand}">Execute My Composite Command</Button>

備考: 他の方法は、Application.Resources項目内のApp.xamlファイルの内側のリソースとして、コマンドを格納することです。 続いて、ビュー内で、-それが、そのリソースを設定した後に作成する必要があります。-呼び出し元をコマンドに追加するには、あなたは、Command="{Binding MyCompositeCommand, Source={StaticResource GlobalCommands}}"を設定することができます。

領域コンテキスト。

Region Context

あなたが、領域内の領域とViewを格納しているView間で、コンテキスト情報を共有したい可能性がある多くの脚本があります。例えば、マスターの詳細-Viewは、ビジネス・エンティティを示す、あるいは、ビジネス・エンティティのために、追加の詳細情報を表示するために、Prism Libraryは、次の図に示すように、領域の内部に読み込まれる、格納される領域とどんなViewの間で、オブジェクトを共有するために、egionContextという名前の概念を使用します。

格納される領域とどんなViewの間で、オブジェクトを共有するために、egionContextという名前の概念を使用します。

シナリオに依存して、あなたは、(識別子のような)情報の一部や共有されたModelを共有するために、選択できます。Viewは、RegionContext、そして、変更通知のための上へ記号を取得することができます。また、Viewは、RegionContextの値を変更することができます。RegionContextを公開する、そして、利用するいくつかの方法があります。:

  • あなたは、Extensible Application Markup Language (XAML)内の領域に、RegionContextを公開することができます。
  • あなたは、コード内の領域に、RegionContextを公開することができます。
  • あなたは、領域内でViewからRegionContextを利用することができます。

備考: そのViewが、DependencyObjectである場合、Prism Libraryは、現在、領域内で、Viewから、RegionContextを利用することをサポートするだけです。あなたのViewが、DependencyObjectでない場合、(たとえば、あなたは、WPFの自動データ・テンプレートを使用して、あなたのViewModelを、直接、領域に追加します)、カスタムRegionBehaviorを、前のRegionContextに、あなたのViewオブジェクトに作成することについて考えてみてください。

Data Contextプロパティについて

About the Data Context Property

データ・コンテクストは、要素は、結合のために使用されるデータ・ソースに関する、それらの親の要素から、情報を継承できる概念です。子要素は、自動的に、それらの親の要素のDataContextを継承します。データは、ビジュアル・ツリーを流れ落ちます。

共有サービス

Shared Services

モジュールを横断する通信のもう1つの方法は、共有サービスを介して行われます。モジュールが読み込まれるとき、モジュールは、それらのサービスをサービス・ロケーターに加えます。通常、サービスは、一般的なインターフェイス型で、サービス・ロケーターから、登録されて、取得されます。これは、モジュールに静的参照を必要とすることなく、モジュールが、他のモジュールで提供されるサービスを使用できます。サービス・インスタンスは、モジュール全体で共有されます。それで、あなたは、データを共有し、そして、モジュール間でメッセージを渡すことができます。

株トレーダーの参考になる実装(株トレーダーRI)では、Marketモジュールは、IMarketFeedServiceの実装を提供します。Positionモジュールは、サービスの位置と解像度を提供する、シェル・アプリケーションの依存関係注入コンテナを使用することにより、これらのサービスを利用します。IMarketFeedServiceは、StockTraderRI.Infrastructure共有アセンブリで見つかるように、他のモジュールで利用されることを示しますが、Marketモジュール内で、直接定義され、そして、他のモジュールと独立して、更新することができるように、このインターフェイスの具体的な実装は、共有する必要はありません。

これらのサービスが、どのようにMEFにエクスポートされているか、確認するには、次のコードの例に示すように、MarketFeedService.csとMarketHistoryService.csファイルを参照してください。PositionモジュールのObservablePositionは、コンストラクタの依存関係の注入を通して、IMarketFeedServiceサービスを受け取ります。

// MarketFeedService.cs [Export(typeof(IMarketFeedService))] [PartCreationPolicy(CreationPolicy.Shared)] public class MarketFeedService : IMarketFeedService, IDisposable { ... }

これは、サービスの利用者は、サービスを提供しているモジュールに静的参照を必要としていないため、モジュールを横断する通信に役立ちます。 このサービスは、モジュールの間で、データーを送信、あるいは、受信するために使用することができます。

備考: いくつかの依存関係注入コンテナは、この例で示すように、属性を使用して依存関係の登録ができます。他のコンテナは、明示的な登録を使用するかもしれません。これらの場合では、登録は、一般的に、Prismが、IModule.Initializeメソッドを呼び出すとき、モジュール読み込みの間に、発生します。 詳しくは、モジュール・アプリケーション開発を参照してください。

イベント集約。

Event Aggregation

Prism Libraryは、アプリケーションの疎く結合したコンポーネントの間で、通信を有効にするイベントの仕組みを提供します。この仕組みは、発行者と購読者が、イベントを通して、情報をやりとりできる、イベント・アグリゲータ・サービスに基づいています。そして、しかし、直接、互いへの参照がありません。

EventAggregatorは、マルチキャストpublish/subscribe機能を提供します。これは、同じイベントを呼び出す複数の発行者で、できることを示しています。そして、それらは、複数の購読者が、同じイベントを聞き取ることができます。モジュールを横断してイベントを公開する、そして、コントローラとプレゼンターのような、ビジネス・ロジック・コード間でメッセージを送信するとき、EventAggregatorを使用することについて考えてみてください。

株トレーダーRIの1つの例は、Process Orderボタンがクリックされる時、そして、注文を正常に処理します。;この場合、他のモジュールは、Viewを更新することができるため、注文がうまく処理されたことを知っている必要があります。

Prism Libraryで作成されるイベントは、型指定されたイベントです。これは、あなたが、アプリケーションを実行する前に、あなたが、エラーを発見するために、コンパイル時の型検査を利用できることを示しています。Prismライブラリでは、EventAggregatorは、特定のEventBaseを配置するために、購読者や発行者を提供します。また、イベント・アグリゲータは、次の図に示すように、複数の発行者と複数の購読者を認めます。

イベント・アグリゲータは、複数の発行者と複数の購読者を認識します。

イベント・アグリゲータは、次の図に示すように、複数の発行者と複数の購読者を認識します。

About .NET Framework Events

使用する.NET フレームワーク・イベントは、疎結合が、要求されない場合、コンポーネントの間の通信のための、最も簡単でわかりやすい方法です。 .NET Frameworkのイベントは、Publish-Subscribeパターンを実装していますが、オブジェクトを購読するために、あなたは、複合アプリケーションでは、通常、別のモジュールに存在する、そのオブジェクトへの直接参照を必要とします。これは、結果として、密接に結合した設計になります。その結果、.NET Framework イベントは、モジュールの間の代わりに、モジュール内での通信のために使用されます。

あなたが、.NET Frameworkイベントを使用する場合、特に、あなたが、静的、あるいは、より長く生きるイベントを購読する、非静的や短命なコンポーネントを持っている場合、あなたは、メモリリークに、とても注意する必要があります。あなたが、購読者の登録を取り消さない場合、それは、発行者によって、生きた状態で維持され、これは、最初のものが、ガーベージ・コレクトするのを防ぎます。

IEventAggregator

IEventAggregator

EventAggregatorクラスは、コンテナのサービスとして提供されます。そして、IEventAggregatorインターフェイスによって取得することができます。 イベント・アグリゲータは、配置、あるいは、構築イベントのための、そして、システム内で、イベントのコレクションを維持することのための役割を果たします。

public interface IEventAggregator
{
    TEventType GetEvent() where TEventType : EventBase;
}

EventAggregatorは、それが、すでに構築されていない場合、その最初のアクセスでイベントを構築します。 これは、イベントが利用できるかどうかに関係なく、判断する必要から発行者や購読者を軽減します。

PubSubEvent

PubSubEvent

発行者と購読者を結合する実際の作業は、PubSubEventクラスによって実行されます。これは、Prism Libraryに含まれている、EventBaseクラスの唯一の実装です。このクラスは、購読者のリストを維持し、そして、購読者へのイベントの発送を処理します。

PubSubEventクラスは、ジェネリック・クラスです。それは、ジェネリック型として定義されているペイロード型を必要とします。これは、強制するのに役立ちます。コンパイル時に、その発行者と購読者は、うまくいくイベント接続のための正しいメソッドを提供します。次に示すコードは、PubSubEventクラスの部分的な定義を示しています。

備考 PubSubEventは、Prism.Core Nugetパッケージに配置される、Prism.Events名前空間で見つかります。

// PubSubEvent.cs
public class PubSubEvent<TPayload> : EventBase
{
    ...
    public SubscriptionToken Subscribe(Action<TPayload> action);
    public SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption);
    public SubscriptionToken Subscribe(Action<TPayload> action, bool keepSubscriberReferenceAlive)
    public SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive)

    public virtual SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive);
    public virtual SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive, Predicate<TPayload> filter);
    public virtual void Publish(TPayload payload);
    public virtual void Unsubscribe(Action<TPayload> subscriber);
    public virtual bool Contains(Action<TPayload> subscriber)
    ...
}

イベントを作成して、公開する

Creating and Publishing Events

次のセクションでは、IEventAggregatorインターフェイスを使用して、PubSubEventを作成し、公開し、そして、購読する方法を説明します。

イベントを作成する

Creating an Event

PubSubEvent<TPayload>は、アプリケーションの、あるいは、モジュールの特定のイベントのための基底クラスであることを意図としています。 TPayLoadは、イベントのペイロード型です。ペイロードは、イベントが公開されるとき、購読者に渡される引数です。

例えば、次のコードは、株トレーダーのリファレンス実装(株トレーダーRI)に、TickerSymbolSelectedEventを表示します。ペイロードは、会社記号が含まれている文字列です。このクラスが空のための実装をどのように行うかに注意します。

public class TickerSymbolSelectedEvent : PubSubEvent<string>{}

備考: 複合アプリケーションでは、イベントは、共通の場所で、定義されるため、複数のモジュール間で、頻繁に共有されます。株トレーダーRIでは、これは、StockTraderRI.Infrastructureプロジェクトの中で実行します。

イベントを公開する

Publishing an Event

発行者は、EventAggregatorからイベントを取得し、そして、Publishメソッドを呼び出すことで、イベントを発生させます。EventAggregatorにアクセスするために、あなたは、クラスのコンストラクタへ、IEventAggregator型のパラメータを追加することで、依存関係の注入を使用することができます。

次のコードは、TickerSymbolSelectedEventの発行を説明します。

this.eventAggregator.GetEvent<TickerSymbolSelectedEvent>().Publish("STOCK0");

イベントを購読する

Subscribing to Events

購読者は、PubSubEventクラス上にオーバーロードした利用できるSubscribeメソッドの1つを使用しているイベントに参加することができます。PubSubEventsを購読するための、いくつかの方法があります。どのオプションが、あなたの必要に最も適切か判断するのを助けるために、次の基準を使用します。:

  • あなたが、イベントを受け取るとき、UI要素を更新できる必要がある場合、UIスレッドで、イベントを受けるために購読します。
  • あなたが、イベントをフィルタリングする必要がある場合、購読するとき、フィルタ・デリゲートを提供します。
  • PubSubEventの購読を購読する、そして、その次に、手動で、中止するとき、あなたが、イベントの処理能力に懸念がある場合、強く参照されたデリゲートを使用することについて考えてみてください。
  • 前述のいずれも適用しない場合、既定の購読を使用します。

次のセクションでは、これらのオプションを説明します。

UIスレッド上で購読する

Subscribing_on_the_UI_Thread

頻繁に、購読者は、イベントに応じて、UI要素を更新する必要があるでしょう。WPFでは、UIスレッドだけは、UI要素を更新することができます。

既定では、購読者は、発行者のスレッド上で、イベントを受け取ります。発行者が、UIスレッドからイベントを送信する場合、購読者は、UIを更新することができます。しかしながら、発行者のスレッドが、バックグラウンド・スレッドである場合、購読者は、直接、UI要素を更新できない場合があります。この場合、購読者は、Dispatcherクラスを使用して、UIスレッドで、更新を予定に入れる必要があります。

Prism Libraryで提供されるPubSubEventは、購読者が、UIスレッド上で自動的にイベントを受け取ることを提供することによって、支援することができます。次のコードの例に示すように、購読者は、これを購読の間、示します。

次のオプションは、ThreadOptionのために利用できます。:

  • PublisherThread。 発行者のスレッド上で、イベントを受けるために、この設定を使用します。これは、既定の設定です。
  • BackgroundThread。.NET Frameworkスレッド-プール・スレッド上で、非同期で、イベントを受信するために、この設定を使用します。
  • UIThread。 UIスレッド上で、イベントを受けるために、この設定を使用します。

備考: UIスレッド上で、PubSubEventsを、購読者に公開するため、EventAggregatorは、最初に、UIスレッド上で、構築される必要があります。

購読フィルタリング

Subscription Filtering

購読者は、公開されたイベントのすべてのインスタンスを取り扱う必要はないかもしれません。これらの場合では、購読者は、フィルタ・パラメータを使用することができます。フィルタ・パラメータは、イベントが、公開されたイベントのペイロードが、必要となる基準のセットと一致する場合、呼び出された購読者コールバックを持つために、判断するために発行されるとき、type System.Predicate<TPayLoad>で、実行されるデリゲートです。ペイロードが、指定された基準を満たさない場合、購読者コールバックは、実行されません。

頻繁に、このフィルタは、次のコードの例に示すように、ラムダ式として指定されます。

備考: Subscribeメソッドは、Prism.Events.SubscriptionToken型の購読トークンを返します。それは、後で、イベントの購読を削除するために使用することができます。コールバック・デリゲートとして、あなたが、匿名型デリゲート、あるいは、ラムダ式を使用するとき、あるいは、あなたが、異なるフィルタで、同じイベント・ハンドラを購読するとき、このトークンは、特に役に立ちます。

備考: これは、コールバック・デリゲート内から、ペイロード・オブジェクトを変更することは、推奨されません。なぜなら、いくつかのスレッドは、同時に、ペイロード・オブジェクトを呼び出すことができます。あなたは、同時実行エラーを避けるために、ペイロードを不変にすることができます。

強い参照を使用して、購読する

Subscribing Using Strong References

あなたが、短い期間に、複数のイベントを呼び出し、そして、処理能力に懸念を抱いた場合、あなたは、強いデリゲート参照で、購読する必要があるかもしれません。あなたが、それを行う場合、購読者を取り除くとき、あなたは、続いて、イベントから、手動で、購読を中止する必要があります。

既定では、PubSubEventは、購読の購読者のハンドラとフィルタに、弱いデリゲート参照を保持します。これは、PubSubEventが保持する参照が、購読者のガーベージ・コレクションを妨げないことを、示しています。弱いデリゲート参照を使用することは、購読者を、購読を中止する必要性を軽減します。そして、適切なガーベージ・コレクションを提供します。

しかしながら、この弱いデリゲート参照を保持することは、対応する強い参照に比べて、より遅くなります。ほとんどアプリケーションのために、 この処理能力は、顕著ではありません。しかし、あなたのアプリケーションが、短い期間に、多数のイベントを発行する場合、あなたは、PubSubEventで、強い参照を使用する必要があるかもしれません。あなたが、強いデリゲート参照を使用する場合、あなたの購読者は、それが、もはや使用されないとき、あなたの購読しているオブジェクトの適切なガーベージ・コレクションを有効にするために、購読を中止する必要があります。

強い参照で購読するには、次のコードの例に示すように、Subscribeメソッドで、keepSubscriberReferenceAliveパラメータを使用します。

FundAddedEvent fundAddedEvent = eventAggregator.GetEvent<FundAddedEvent>();

bool keepSubscriberReferenceAlive = true;

fundAddedEvent.Subscribe(FundAddedEventHandler, ThreadOption.UIThread, keepSubscriberReferenceAlive, fundOrder => fundOrder.CustomerId == _customerId);

keepSubscriberReferenceAliveパラメータは、type boolです。:

trueに設定されると、イベント・インスタンスは、購読者インスタンスに強い参照を保有します。それにより、それが、ガベージコレクションを取得することができません。どのように、購読を中止するかについていは、このトピックの後の、イベントから購読を中止するの項目を参照してください。

falseに設定されたとき、(このパラメータを省略したときの既定の値)、イベントは、購読者インスタンスに、弱い参照を保持します。それによって、それへの他の参照がないとき、ガーベジコレクタが、購読者インスタンスを取り除くことができます。購読者インスタンスが、収集されたとき、イベントは、自動的に、購読を中止します。

既定の購読

Default Subscriptions

最少限、あるいは、既定の購読のため、購読者は、イベント通知を受け取る適切な署名で、コールバック・メソッドを提供する必要があります。例えば、 次のコードの例に示すように、TickerSymbolSelectedEventのためのハンドラは、文字列パラメータを取得するメソッドを必要とします。

public TrendLineViewModel(IMarketHistoryService marketHistoryService, IEventAggregator eventAggregator)
{
    ... eventAggregator.GetEvent<TickerSymbolSelectedEvent>().Subscribe(this.TickerSymbolChanged);
}

public void TickerSymbolChanged(string newTickerSymbol)
{
    MarketHistoryCollection newHistoryCollection = this.marketHistoryService.GetPriceHistory(newTickerSymbol);

    this.TickerSymbol = newTickerSymbol;
    this.HistoryCollection = newHistoryCollection;
}

イベントから購読を中止する

Unsubscribing from an Event

あなたの購読者が、イベントを受けることをもはや望まない場合、あなたの購読者のハンドラを使用して、あなたは、購読を中止することができます。 あるいは、あなたは、購読トークンを使用することで、購読を中止することができます。

次のコード例は、どのように、ハンドラに、直接、購読を中止するかを示します。

FundAddedEvent fundAddedEvent = this.eventAggregator.GetEvent<FundAddedEvent>();

fundAddedEvent.Subscribe(FundAddedEventHandler, ThreadOption.PublisherThread);

fundAddedEvent.Unsubscribe(FundAddedEventHandler);

次のコード例は、購読トークンで、どのように、購読を中止するかを示します。トークンは、Subscribeメソッドからの戻り値として、指定されます。

FundAddedEvent fundAddedEvent = this.eventAggregator.GetEvent<FundAddedEvent>();

subscriptionToken = fundAddedEvent.Subscribe(FundAddedEventHandler, ThreadOption.UIThread, false, fundOrder => fundOrder.CustomerId == this.customerId);

fundAddedEvent.Unsubscribe(subscriptionToken);

詳細情報

More_Information

弱い参照の詳細については、MSDNの弱い参照を参照してください。

このエントリーをはてなブックマークに追加

Home PC C# Illustration

Copyright (C) 2011 Horio Kazuhiko(kukekko) All Rights Reserved.
kukekko@gmail.com
ご連絡の際は、お問い合わせページのURLの明記をお願いします。
「掲載内容は私自身の見解であり、所属する組織を代表するものではありません。」