ユーザー定義バインディングの作成
システムから提供されないバインディングを作成する方法はいくつかあります。
- バインディング要素を格納するコンテナである CustomBinding クラスに基づいてカスタム バインディングを作成します。次に、カスタム バインディングをサービス エンドポイントに追加します。カスタム バインディングは、プログラムで作成することも、アプリケーションの構成ファイルに作成することもできます。アプリケーション構成ファイルのバインディング要素を使用するには、バインディング要素で BindingElementExtensionElement を拡張する必要があります。カスタム バインディング詳細については、 、「カスタム バインディング」および「CustomBinding」を参照してください。
- 標準バインディングの派生クラスを作成できます。たとえば、WSHttpBinding の派生クラスを作成して CreateBindingElements メソッドを上書きし、バインディング要素を取得してカスタム バインディングを挿入したり、セキュリティ用の特定の値を確立したりできます。
- 新しい Binding 型を作成して、バインディング実装全体を完全に制御することができます。
バインディング要素の順序
各バインディング要素は、メッセージの送信または受信時の処理手順を表します。実行時に、バインディング要素により、送受信チャネル スタックの作成に必要なチャネルとリスナが作成されます。
バインディング要素には主に、プロトコル バインディング要素、エンコーディング バインディング要素、トランスポート バインディング要素という 3 つの種類があります。
プロトコル バインディング要素 : この要素はメッセージで動作する上位処理ステップを表します。このバインディング要素で作成したチャネルとリスナーを使って、メッセージ内容の追加、削除、変更が可能です。特定のバインディングには、それぞれが BindingElement を継承する任意の数のプロトコル バインディング要素を含めることができます。Windows Communication Foundation (WCF) には、ReliableSessionBindingElement や SymmetricSecurityBindingElement などのプロトコル バインディング要素がいくつか含まれます。
エンコーディング バインディング要素 : この要素は、メッセージとネットワーク転送が可能なエンコーディングとの間の変換を表します。一般的な WCF バインディングには、エンコーディング バインディング要素が 1 つだけ含まれます。エンコーディング バインディング要素の例として、MtomMessageEncodingBindingElement、BinaryMessageEncodingBindingElement、TextMessageEncodingBindingElement などがあります。エンコーディング バインディング要素がバインディングに指定されていない場合、既定のエンコーディングが使用されます。既定値は、トランスポートが HTTP の場合はテキスト、それ以外の場合はバイナリです。
トランスポート バインディング要素 : この要素は、トランスポート プロトコルでのエンコーディング メッセージの送信を表します。一般的な WCF バインディングには、TransportBindingElement から派生したトランスポート バインディング要素が 1 つだけ含まれます。トランスポート バインディング要素の例として、TcpTransportBindingElement、HttpTransportBindingElement、NamedPipeTransportBindingElement などがあります。
新しいバインディングを作成する場合、バインディング要素の追加順序が重要になります。バインディング要素は必ず次の順序で追加します。
層 | オプション | 必須 |
---|---|---|
トランザクション フロー |
× |
|
信頼性 |
System.ServiceModel.Channels.ReliableSessionBindingElement |
× |
セキュリティ |
× |
|
複合二重 |
× |
|
エンコーディング |
テキスト、バイナリ、MTOM、カスタム |
○* |
トランスポート |
TCP、名前付きパイプ、HTTP、HTTPS、MSMQ、およびカスタム |
○ |
*エンコーディングは各バインディングに必要であるため、エンコーディングが指定されていない場合、WCF は既定のエンコーディングを自動的に追加します。既定値は、HTTP および HTTPS トランスポートの場合はテキスト/XML、それ以外の場合はバイナリです。
新しいバインディング要素の作成
WCF が提供する BindingElement から派生した型のほかに、独自のバインディング要素を作成できます。これにより、他のシステムが提供する型を使ってスタックに組み込むことのできる独自の BindingElement を作成して、バインディングのスタックを作成する方法や、バインディングのスタックに追加するコンポーネントをカスタマイズできます。
たとえば、メッセージをデータベースに記録する機能を持つ LoggingBindingElement
を実装する場合、それをチャネル スタックのトランスポート チャネルの上に配置する必要があります。この場合、アプリケーションでは、次の例に示すように、TcpTransportBindingElement と共に LoggingBindingElement
が組み込まれたカスタム バインディングが作成されます。
Binding customBinding = new CustomBinding(
new LoggingBindingElement(),
new TcpTransportBindingElement()
);
新しいバインディング要素を記述する方法は、機能性の詳細によって異なります。サンプルの 1 つ (Transport: UDP) を使用して、1 つの種類のバインディング要素の実装方法を詳細に説明します。
新しいバインディングの作成
ユーザーが作成するバインディング要素は、2 つの方法で使用できます。前のセクションでは、カスタム バインディングを使用する 1 番目の方法が説明されています。カスタム バインディングを使用すれば、バインディング要素の任意のセットに基づいて独自のバインディングを作成できます。ユーザーが作成するバインディング エレメントもこれに含まれます。
2 つ以上のアプリケーションでバインディングを使用する場合、独自のバインディングを作成し、Binding を拡張します。これにより、カスタム バインディングを使う必要があるたびに、手動でカスタム バインディングを作成する必要性を回避できます。ユーザー定義のバインディングを使用して、バインディングの動作を定義したり、ユーザー定義のバインディング要素を格納することができます。また、事前パッケージングであるため、使用するたびにバインディングを再作成する必要はありません**。
ユーザー定義のバインディングは、少なくとも CreateBindingElements メソッドと Scheme プロパティを実装する必要があります。
CreateBindingElements メソッドは、バインディングのバインディング要素を格納している新しい BindingElementCollection を返します。このコレクションは順序付けられており、始めにプロトコル バインディング要素を格納し、次にエンコーディング バインディング要素、その次にトランスポート バインディング要素を格納する必要があります。WCF システム指定のバインディング要素を使用する場合、カスタム バインディングに指定されているバインディング要素の順序ルールに従う必要があります。このコレクションから、ユーザー定義のバインディング クラス内で参照されるオブジェクトを参照すべきではありません。このため、バインディングの作成者は、CreateBindingElements を呼び出すたびに BindingElementCollection の Clone() を返す必要があります。
Scheme プロパティは、バインディングで使用するトランスポート プロトコルの URI スキームを表します。たとえば、WSHttpBinding および NetTcpBinding は、それぞれの Scheme プロパティから "http" および "net.tcp" を返します。
ユーザー定義バインディングのオプション メソッドとプロパティの完全な一覧については、Binding を参照してください。
例
このサンプルでは、プロファイル バインディングを、Binding から派生した SampleProfileUdpBinding
に実装します。SampleProfileUdpBinding
は最大で 4 つのバインディング要素を格納します。1 つはユーザー作成の UdpTransportBindingElement
で、後の 3 つはシステム指定の TextMessageEncodingBindingElement
、 CompositeDuplexBindingElement
、ReliableSessionBindingElement
です。
public override BindingElementCollection CreateBindingElements()
{
BindingElementCollection bindingElements = new BindingElementCollection();
if (ReliableSessionEnabled)
{
bindingElements.Add(session);
bindingElements.Add(compositeDuplex);
}
bindingElements.Add(encoding);
bindingElements.Add(transport);
return bindingElements.Clone();
}
双方向コントラクトのセキュリティ制限
すべてのバインディング要素どうしに互換性があるわけではありません。特に双方向コントラクトで使用する場合、セキュリティ バインディング要素にはいくつかの制限があります。
ワンショット セキュリティ
<message> 構成要素の negotiateServiceCredential
属性を false に設定すると、必要なすべてのセキュリティ資格情報を 1 つのメッセージで送信する、"ワンショット" セキュリティを実装できます。
ワンショット認証は双方向コントラクトでは動作しません。
要求/応答コントラクトでは、セキュリティ バインディング要素の下にあるバインディング スタックで IRequestChannel インスタンスまたは IRequestSessionChannel インスタンスの作成がサポートされている場合にのみ、ワンショット認証は動作します。
一方向コントラクトでは、セキュリティ バインディング要素の下にあるバインディング スタックで IRequestChannel、IRequestSessionChannel、IOutputChannel、または IOutputSessionChannel の各インスタンスの作成がサポートされている場合にのみ、ワンショット認証は動作します。
Cookie モードのセキュリティ コンテキスト トークン
Cookie モードのセキュリティ コンテキスト トークンは、双方向コントラクトでは使用できません。
要求/応答コントラクトでは、セキュリティ バインディング要素の下にあるバインディング スタックで IRequestChannel インスタンスまたは IRequestSessionChannel インスタンスの作成がサポートされている場合にのみ、Cookie モードのセキュリティ コンテキスト トークンは動作します。
一方向コントラクトでは、セキュリティ バインディング要素の下にあるバインディング スタックで IRequestChannel インスタンスまたは IRequestSessionChannel インスタンスの作成がサポートされている場合にのみ、Cookie モードのセキュリティ コンテキスト トークンは動作します。
セッション モードのセキュリティ コンテキスト トークン
双方向コントラクトでは、セッション モードの SCT (セキュリティ コンテキスト トークン) は、セキュリティ バインディング要素の下にあるバインディング スタックで IDuplexChannel インスタンスまたは IDuplexSessionChannel インスタンスの作成がサポートされている場合に動作します。
要求/応答コントラクトでは、セッション モードの SCT は、セキュリティ バインディング要素の下にあるバインディング スタックで IDuplexChannel、IDuplexSessionChannel、IRequestChannel、または IRequestSessionChannel の各インスタンスの作成がサポートされている場合に動作します。
一方向コントラクトでは、セッション モードの SCT は、セキュリティ バインディング要素の下にあるバインディング スタックで IDuplexChannel、IDuplexSessionChannel、IRequestChannel、または IRequestSessionChannel の各インスタンスの作成がサポートされている場合に動作します。
標準バインディングからの派生
まったく新しいバインディング クラスを作成する代わりに、システムから提供される既存のバインディングの 1 つを拡張することができます。前述の場合と同様、CreateBindingElements メソッドと Scheme プロパティを上書きする必要があります。