ディスパッチャの拡張
サービス モデル レイヤは、基になるチャネルから受信メッセージをプルし、そのメッセージをアプリケーション コードでのメソッド呼び出しに変換し、結果を呼び出し元に送信する役割があります。サービス モデル拡張は、クライアントやディスパッチャの機能、カスタム動作、メッセージとパラメータの途中受信、およびその他の拡張機能に関連する実行や通信の動作と機能を変更または実装します。
ここでは、Windows Communication Foundation (WCF) サービス アプリケーションで DispatchRuntime クラスと DispatchOperation クラスを使用して、ディスパッチャの既定の実行動作を変更したり、メッセージ、パラメータ、または戻り値を、チャネル レイヤから送信または取得する前後に途中受信したり、変更したりする方法について説明します。同等のクライアント ランタイム メッセージ処理の詳細については、「クライアントの拡張」を参照してください。さまざまなランタイム カスタマイズ オブジェクト間で共有される状態にアクセスするときに IExtensibleObject 型が果たす役割について理解するには、「拡張可能オブジェクト」を参照してください。
ディスパッチャ
サービス モデル レイヤは、開発者のプログラミング モデルと基になるメッセージ交換 (一般的に、チャネル レイヤと呼ばれます) の間の変換を実行します。WCF では、チャネル ディスパッチャとエンドポイント ディスパッチャ (それぞれ ChannelDispatcher と EndpointDispatcher) は、新しいチャネルを受け入れて、メッセージ、操作ディスパッチ、操作呼び出し、および応答処理を受信するためのサービス コンポーネントです。ディスパッチャ オブジェクトは、受信者のオブジェクトですが、双方向サービスでのコールバック コントラクトの実装も、検査、変更、または拡張のためにディスパッチャ オブジェクトを公開します。
チャネル ディスパッチャ (およびコンパニオン IChannelListener) は、基になるチャネルからメッセージをプルし、そのメッセージをそれぞれのエンドポイント ディスパッチャに渡します。各エンドポイント ディスパッチャには、メッセージを適切な DispatchOperation にルーティングする DispatchRuntime があります。これには、操作を実装するメソッドを呼び出す役割があります。さまざまなオプションの拡張クラスおよび必須の拡張クラスが呼び出され、関与します。ここでは、この要素を組み合わせる方法、基本機能を拡張するためにプロパティを変更し、ユーザーのコードをプラグインする方法について説明します。
ディスパッチャのプロパティと変更されたカスタマイズ オブジェクトは、サービス、エンドポイント、コントラクト、または操作の動作オブジェクトを使用して挿入します。ここでは、動作を使用する方法については説明しません。ディスパッチャの変更を挿入するために使用する型の詳細については、「方法 : 企業内のエンドポイントをロックダウンする」を参照してください。
次の図は、サービスを構成する項目の概念図を示しています。
チャネル ディスパッチャ
特定の URI (リッスン URI と呼ばれます) にある IChannelListener をサービスのインスタンスと関連付けるために、ChannelDispatcher オブジェクトが作成されます。したがって、各 ServiceHost オブジェクトは、多数の ChannelDispatcher オブジェクトを持つ可能性があります。それらの各オブジェクトは、1 つのリスナとリッスン URI にだけ関連付けられます。メッセージが到着すると、ChannelDispatcher が、関連する各 EndpointDispatcher オブジェクトにエンドポイントがメッセージを受け入れ可能かどうかを問い合わせ、受け入れ可能ならメッセージを渡します。
ChannelDispatcher オブジェクトに定義されているチャネル セッションの有効期間および動作を制御するすべてのプロパティは、検査および変更可能です。これには、カスタムのチャネル初期化子、チャネル リスナ、ホスト、関連する InstanceContext などがあります。
エンドポイント ディスパッチャ
メッセージの送信先アドレスが AddressFilter プロパティに一致しており、メッセージ アクションが ContractFilter プロパティに一致しているときは、EndpointDispatcher オブジェクトが ChannelDispatcher から送信されたメッセージの処理を担当します。2 つの EndpointDispatcher オブジェクトが 1 つのメッセージを受信する可能性があるときは、FilterPriority プロパティの値によって、優先度の高いエンドポイントが決まります。
EndpointDispatcher を使用して、2 つの主要サービス モデル拡張ポイントである DispatchRuntime クラスと DispatchOperation クラスを取得します。このクラスは、ディスパッチャの処理をカスタマイズするときに使用できます。DispatchRuntime クラスを使用すると、コントラクトのスコープで (つまり、コントラクトにあるすべてのメッセージに対して) ディスパッチャを途中受信および拡張できます。DispatchOperation クラスを使用すると、操作のスコープで (つまり、操作にあるすべてのメッセージに対して) ディスパッチャを途中受信および拡張できます。
シナリオ
ディスパッチャを拡張する理由としては、次のようなさまざまなものがあります。
カスタム メッセージの検証。特定のスキーマに対してメッセージが有効になるようにすることができます。これは、メッセージ インターセプタ インターフェイスを実装することで対応できます。例については、「Message Inspectors」を参照してください。
カスタム メッセージのログ記録。エンドポイントを通過するアプリケーション メッセージの一部を検査して記録することができます。これはメッセージ インターセプタ インターフェイスで実行可能です。
カスタム メッセージの変換。ランタイムのメッセージに特定の変換を適用できます (バージョン管理の場合など)。これもまた、メッセージ インターセプタ インターフェイスで実行可能です。
カスタム データ モデル。既定で WCF でサポートされているモデル (つまり、System.Runtime.Serialization.DataContractSerializer、System.Xml.Serialization.XmlSerializer、および未加工メッセージ) 以外のデータ シリアル化モデルを持つことができます。これは、メッセージ フォーマッタ インターフェイスを実装することで対応できます。例については、「Operation Formatter And Operation Selector」を参照してください。
カスタム パラメータの検証。XML ではなく、型指定されたパラメータが有効になるようにすることができます。これは、パラメータ インスペクタ インターフェイスを使用して実行できます。例については、「Parameter Filter」を参照してください。
カスタム操作ディスパッチ。アクション以外の場所、たとえば、本文要素やカスタム メッセージ プロパティでディスパッチを実装できます。これは、IDispatchOperationSelector インターフェイスを使用して実行できます。例については、「Operation Formatter And Operation Selector」を参照してください。
オブジェクト プール。呼び出しごとに新しいインスタンスを割り当てるのではなく、インスタンスをプールできます。これは、インスタンス プロバイダ インターフェイスを使用して実装できます。例については、「Pooling」を参照してください。
インスタンス リース。インスタンスの有効期間にリース パターンを実装できます。これは、.NET Framework リモートのパターンに似ています。これは、インスタンス コンテキスト有効期間インターフェイスを使用して実行できます。
カスタム エラー処理。ローカル エラーの処理方法とエラーをクライアントに戻す方法を制御できます。これは、IErrorHandler インターフェイスを使用して実装できます。
カスタム承認動作。コントラクトまたは操作のランタイム要素を拡張し、メッセージに存在するトークンに基づくセキュリティ チェックを追加することによって、カスタムのアクセス制御を実装できます。これは、メッセージ インターセプタ インターフェイスまたはパラメータ インターセプタ インターフェイスを使用して実行できます。例については、「Security Extensibility Samples」を参照してください。
注意 : セキュリティ プロパティを変更すると、WCF アプリケーションのセキュリティを損なう可能性があるので、注意してセキュリティ関連の変更を行い、配置する前に十分テストすることをお勧めします。 カスタム WCF ランタイム バリデータ。WCF アプリケーションに対して企業レベルのポリシーを実施するために、サービス、コントラクト、およびバインディングを調査するカスタム バリデータをインストールできます。たとえば、「方法 : 企業内のエンドポイントをロックダウンする」を参照してください。
DispatchRuntime クラスの使用
DispatchRuntime クラスを使用して、サービスまたは個別のエンドポイントの既定動作を変更するか、またはカスタム変更を実装したオブジェクトを次のサービス プロセス (または双方向クライアントの場合、クライアント プロセス) の一方または両方に挿入します。
- 受信メッセージをオブジェクトに変換し、メソッド呼び出しとしてサービス オブジェクト上でそれらのオブジェクトを解放します。
- サービス操作呼び出しに対する応答から受信したオブジェクトを送信メッセージに変換します。
DispatchRuntime を使用すると、メッセージが認識されない場合でも、特定のコントラクト全体のすべてのメッセージについて、特定のチャネルまたはエンドポイント ディスパッチャを途中受信および拡張できます。コントラクト内のどの宣言にも一致しないメッセージが到着した場合、UnhandledDispatchOperation プロパティにより返された操作にディスパッチされます。特定の操作についてすべてのメッセージを途中受信または拡張する方法については、DispatchOperation クラスを参照してください。
DispatchRuntime クラスによって公開されているディスパッチャ拡張性は次の 4 つの領域に大別できます。
- DispatchRuntime のプロパティおよび ChannelDispatcher によって返される関連チャネル ディスパッチャのプロパティを使用して、チャネル コンポーネントが、チャネル ディスパッチャによるチャネルのアクセプトおよびクローズ方法をカスタマイズします。この分類に属するプロパティとして、ChannelInitializers プロパティおよび InputSessionShutdownHandlers があります。
- メッセージ コンポーネントを、処理されるメッセージごとにカスタマイズします。この分類に属するプロパティとして、MessageInspectors、OperationSelector、Operations、ErrorHandlers があります。
- インスタンス コンポーネントが、特定のサービス型のインスタンスの作成、有効期間、破棄をカスタマイズします。サービス オブジェクトの有効期間の詳細については、InstanceContextMode プロパティを参照してください。このカテゴリには、InstanceContextInitializers プロパティおよび InstanceProvider プロパティが含まれます。
- セキュリティ関連コンポーネントは、次のプロパティを使用できます。
- SecurityAuditLogLocation は、監査イベントが出力される場所を示します。
- ImpersonateCallerForAllOperations は、受信メッセージによって提供される資格情報を使用してサービスが偽装を試みるかどうかを制御します。
- MessageAuthenticationAuditLevel は、SecurityAuditLogLocation によって指定されたイベント ログに、メッセージ認証成功イベントを出力するかどうかを制御します。
- PrincipalPermissionMode は、CurrentPrincipal プロパティの設定方法を制御します。
- ServiceAuthorizationAuditLevel は、承認イベントの監査の実行方法を指定します。
- SuppressAuditFailure は、ログ記録処理中に発生した致命的でない例外を抑制するかどうかを指定します。
カスタムの拡張オブジェクトは通常、DispatchRuntime プロパティに割り当てるか、サービス動作 (IServiceBehavior を実装するオブジェクト)、コントラクト動作 (IContractBehavior を実装するオブジェクト)、またはエンドポイント動作 (IEndpointBehavior を実装するオブジェクト) によってコレクションに挿入します。次に、インストール動作オブジェクトを、プログラムで直接、またはカスタムの BehaviorExtensionElement オブジェクトを実装して適切な動作コレクションに追加し、アプリケーション構成ファイルを使用して動作を挿入できるようにします。
双方向クライアント (双方向サービスによって指定されたコールバック コントラクトを実装したクライアント) にも、CallbackDispatchRuntime プロパティを使用してアクセスできる DispatchRuntime オブジェクトがあります。
DispatchOperation クラスの使用
DispatchOperation クラスは、1 つのサービス操作のスコープ内だけに適用されるカスタムの拡張を実現するために、ランタイムに対して変更または挿入を行う場所です (コントラクト中のすべてのメッセージに対するサービスのランタイム動作を変更するには、DispatchRuntime クラスを使用します)。
カスタムのサービス動作オブジェクトを使用して、DispatchOperation の変更をインストールします。
Operations プロパティを使用して、特定のサービス操作を表す DispatchOperation オブジェクトを検索します。
次のプロパティは、操作レベルでランタイム実行を制御します。
- Action、ReplyAction、FaultContractInfos、IsOneWay、IsTerminating、および Name の各プロパティは、操作の値をそれぞれ取得します。
- TransactionAutoComplete と TransactionRequired は、トランザクション動作を指定します。
- ReleaseInstanceBeforeCall プロパティと ReleaseInstanceAfterCall プロパティは、InstanceContext に応じてユーザー定義サービス オブジェクトの有効期間を制御します。
- DeserializeRequest、SerializeReply、および Formatter の各プロパティでは、メッセージからオブジェクトへの変換およびオブジェクトからメッセージへの変換を明示的に制御できます。
- Impersonation プロパティは、操作の偽装レベルを指定します。
- CallContextInitializers プロパティは、操作のカスタム呼び出しコンテキスト拡張を挿入します。
- AutoDisposeParameters プロパティは、パラメータ オブジェクトが破棄されるタイミングを制御します。
- Invoker プロパティは、カスタムの呼び出しオブジェクトを挿入します。
- ParameterInspectors プロパティでは、パラメータと戻り値の検査または変更に使用できるカスタム パラメータ インスペクタを挿入できます。
関連項目
タスク
方法 : サービスのメッセージを検査および変更する
方法 : パラメータを検査または変更する
方法 : 企業内のエンドポイントをロックダウンする