クライアントの拡張
呼び出し側のアプリケーションでは、サービス モデル レイヤーが、アプリケーション コードでのメソッド呼び出しを送信メッセージに変換し、それらを基になるチャネルにプッシュし、結果をアプリケーション コードで戻り値と出力パラメーターに変換して、変換結果を呼び出し側に返します。 サービス モデル拡張は、クライアントやディスパッチャーの機能、カスタム動作、メッセージとパラメーターの途中受信、およびその他の拡張機能に関連する実行や通信の動作と機能を変更または実装します。
ここでは、Windows Communication Foundation (WCF) クライアント アプリケーションで ClientRuntime クラスと ClientOperation クラスを使用して、 クライアントの既定の実行動作を変更したり、メッセージ、パラメーター、または戻り値を、チャネル レイヤーから送信または取得する前後に途中受信したり、変更したりする方法について説明します。 サービス ランタイムの拡張の詳細については、「ディスパッチャーの拡張」を参照してください。 カスタマイズ オブジェクトを変更してクライアント ランタイムに挿入する動作の詳細については、「動作を使用したランタイムの構成と拡張」を参照してください。
クライアント
クライアントでは、WCF クライアント オブジェクトまたはクライアント チャネルが、メソッド呼び出しを送信メッセージに、受信メッセージを操作結果に変換し、この操作結果を呼び出し側のアプリケーションに返します (クライアントの種類の詳細については、WCF クライアント アーキテクチャに関するページを参照してください)。
WCF クライアントの種類には、このようなエンドポイント レベルと操作レベルの機能を処理するランタイム型があります。 アプリケーションが操作を呼び出すと、ClientOperation が送信オブジェクトをメッセージに変換し、インターセプターを処理し、送信呼び出しがターゲット コントラクトに適合することを確認してから、送信メッセージを ClientRuntime に渡します。このクラスは、送信チャネル (双方向サービスの場合には、さらに受信チャネル) の作成と管理、追加の送信メッセージ処理 (ヘッダーの変更など)、メッセージ インターセプターの両方向での処理、および適切なクライアント側 DispatchRuntime オブジェクトへの受信双方向呼び出しのルーティングを実行します。 ClientOperation と ClientRuntime は、共にメッセージ (エラーを含む) がクライアントに返されるときに同様のサービスを提供します。
この 2 つのランタイム クラスは、WCF のクライアント オブジェクトとチャネルの処理をカスタマイズするための主要な拡張機能です。 ClientRuntime クラスは、ユーザーが、コントラクト内のすべてのメッセージについてクライアント実行を途中受信して拡張できるようにします。 ClientOperation クラスは、ユーザーが、特定の操作内のすべてのメッセージについてクライアント実行を途中受信して拡張できるようにします。
プロパティの変更やカスタマイズの挿入は、コントラクト、エンドポイント、および操作の各動作を使用して行います。 これらの種類の動作を使用してクライアント ランタイムのカスタマイズを実行する方法の詳細については、「動作を使用したランタイムの構成と拡張」を参照してください。
シナリオ
クライアント システムを拡張する理由としては、次のようなさまざまなものがあります。
カスタム メッセージの検証。 特定のスキーマに対してメッセージが有効になるようにする必要が生じる場合があります。 これは、IClientMessageInspector インターフェイスを実装し、この実装を MessageInspectors プロパティに割り当てることで可能になります。 例については、「方法: クライアントでメッセージを検査または変更する」および「方法: クライアントでメッセージを検査または変更する」を参照してください。
カスタム メッセージのログ記録。 エンドポイントを通過するアプリケーション メッセージの一部を検査して記録する必要が生じる場合があります。 これはメッセージ インターセプター インターフェイスで実行可能です。
カスタム メッセージの変換。 アプリケーション コードを変更するのではなく、ランタイムのメッセージに特定の変換を適用する必要が生じる場合があります (バージョン管理の場合など)。 これもまた、メッセージ インターセプター インターフェイスで実行可能です。
カスタム データ モデル。 WCF で既定でサポートされているオブジェクト (つまり、System.Runtime.Serialization.DataContractSerializer オブジェクト、System.Xml.Serialization.XmlSerializer オブジェクト、および System.ServiceModel.Channels.Message オブジェクト) 以外のデータ モデルやシリアル化モデルをユーザーが必要とする場合があります。 これは、メッセージ フォーマッタ インターフェイスを実装することで対応できます。 詳細については、System.ServiceModel.Dispatcher.IClientMessageFormatter および ClientOperation.Formatter プロパティのトピックを参照してください。
カスタム パラメーターの検証。 XML ではなく、型指定されたパラメーターが有効になるようにする必要が生じる場合があります。 これは、パラメーター インスペクター インターフェイスを使用して実行できます。 例については、「方法: パラメーターを検査または変更する」または「クライアント検証」を参照してください。
ClientRuntime クラスの使用
ClientRuntime クラスは、メッセージを途中受信してクライアントの動作を拡張する拡張オブジェクトを追加できる拡張ポイントです。 途中受信オブジェクトには、特定のコントラクト内のすべてのメッセージを処理する、特定の操作用のメッセージだけを処理する、カスタムのチャネル初期化を実行する、その他のカスタム クライアント アプリケーションの動作を実行する、などの機能があります。
CallbackDispatchRuntime プロパティは、サービス側開始のコールバック クライアント用のディスパッチ ランタイム オブジェクトを返します。
OperationSelector プロパティは、カスタムの操作セレクター オブジェクトを受け取ります。
ChannelInitializers プロパティを使用すると、クライアント チャネルを検査または変更できるチャネル初期化子を追加できます。
Operations プロパティは、ClientOperation オブジェクトのコレクションを取得します。このコレクションにカスタムのメッセージ インターセプターを追加すれば、その操作のメッセージに固有の機能を提供できます。
ManualAddressing プロパティをアプリケーションで使用すると、自動アドレス指定ヘッダーをオフにしてアドレス指定を直接制御できます。
Via プロパティは、トランスポート レベルでメッセージの送信先の値を設定して、メッセージの中継者やその他のシナリオをサポートします。
MessageInspectors プロパティは、IClientMessageInspector オブジェクトのコレクションを取得します。このコレクションには、WCF クライアント経由で配信されるすべてのメッセージに対応するカスタム メッセージ インターセプターを追加できます。
また、コントラクト情報を取得するその他のプロパティも多数用意されています。
WCF クライアントが双方向 WCF クライアントの場合は、次のプロパティもコールバック WCF クライアント情報を取得します。
WCF のクライアント実行を WCF クライアント全体で拡張するには、ClientRuntime クラスに用意されているプロパティを調べ、目的の機能を作成するために、プロパティを変更するか、またはインターフェイスを実装してプロパティに追加するかを確認します。 作成する特定の拡張を選択した後は、適切な ClientRuntime プロパティにその拡張を挿入します。挿入するには、実行時に ClientRuntime クラスにアクセスを提供するクライアント動作を実装します。
カスタム拡張オブジェクトは、操作動作 (IOperationBehavior を実装するオブジェクト)、コントラクト動作 (IContractBehavior を実装するオブジェクト)、またはエンドポイント動作 (IEndpointBehavior を実装するオブジェクト) を使用して、コレクションに挿入できます。 インストール動作オブジェクトは、プログラムで直接に、または宣言を介して (カスタム属性を実装して)、さらにアプリケーション構成ファイルを使用して動作を挿入できるようにするカスタム BehaviorExtensionElement オブジェクトを実装することにより、適切な動作コレクションに追加されます。 詳細については、「動作を使用したランタイムの構成と拡張」を参照してください。
WCF クライアント全体でのインターセプトを示す例については、「方法: クライアントでメッセージを検査または変更する」を参照してください。
ClientOperation クラスの使用
ClientOperation クラスは、1 つのサービス操作のスコープ内だけに適用されるカスタムの拡張を実現するために、クライアント ランタイムに対して変更または挿入を行う場所です。 (コントラクト中のすべてのメッセージに対するクライアントのランタイム動作を変更するには、ClientRuntime クラスを使用します。)
Operations プロパティを使用して、特定のサービス操作を表す ClientOperation オブジェクトを検索します。 次の各プロパティを使用すると、カスタム オブジェクトを WCF クライアント システムに挿入できます。
Formatter プロパティは、特定の操作用に IClientMessageFormatter のカスタムの実装を挿入したり、現在のフォーマッタを変更するために使用します。
ParameterInspectors プロパティは、IParameterInspector のカスタムの実装を挿入したり、現在の実装を変更するために使用します。
次の各プロパティを使用すると、フォーマッタおよびカスタムのパラメーター インスペクターとやり取りしてシステムを変更できます。
SerializeRequest プロパティは、送信メッセージのシリアル化を制御するために使用します。
DeserializeReply プロパティは、受信メッセージの逆シリアル化を制御するために使用します。
要求メッセージの WS-Addressing 操作を制御する場合に Action プロパティを使用します。
BeginMethod プロパティと EndMethod プロパティは、非同期操作に関連付けられる WCF クライアント メソッドを指定するために使用します。
FaultContractInfos プロパティは、SOAP エラーの際に詳細な型として表示できる型を含むコレクションを取得するために使用します。
IsInitiating プロパティおよび IsTerminating プロパティは、操作が呼び出されたとき、それぞれセッションを起動するか終了するかを制御するために使用します。
IsOneWay プロパティは、操作が一方向の操作であるかどうかを制御するために使用します。
Parent プロパティは、ClientRuntime の親オブジェクトを取得するために使用します。
Name プロパティは、操作の名前を取得するために使用します。
SyncMethod プロパティは、操作にマップされるメソッドを制御するために使用します。
WCF のクライアント実行を 1 つのサービス操作でのみ拡張するには、ClientOperation クラスに用意されているプロパティを調べ、目的の機能を作成するために、プロパティを変更するか、またはインターフェイスを実装してプロパティに追加するかを確認します。 作成する特定の拡張を選択した後は、適切な ClientOperation プロパティにその拡張を挿入します。挿入するには、実行時に ClientOperation クラスにアクセスを提供するクライアント動作を実装します。 これで、その動作の内部で、ClientRuntime プロパティを要件に合わせて変更できるようになります。
通常は、操作動作 (IOperationBehavior を実装するオブジェクト) の実装で十分ですが、エンドポイント動作とコントラクト動作を使用して、特定の操作の OperationDescription を検索し、これに動作を関連付けても同じことを実現できます。 詳細については、「動作を使用したランタイムの構成と拡張」を参照してください。
構成からカスタム動作を使用するには、カスタム動作構成セクション ハンドラーを使用して動作をインストールします。 また、カスタム属性を作成することによって動作をインストールすることもできます。
WCF クライアント全体でのインターセプトを示す例については、「方法: パラメーターを検査または変更する」を参照してください。