このトピックでは、バインドとバインド要素の構成とメタデータのサポートを有効にする方法について説明します。
構成とメタデータの概要
このトピックでは、次のタスクについて説明します。これは、[ 開発チャネル ] タスク リストのオプション項目 1、2、および 4 です。
バインド要素に対する構成ファイルのサポートを有効にする。
バインドに対する構成ファイルのサポートを有効にする。
バインディング要素の WSDL およびポリシー アサーションのエクスポート。
バインド要素またはバインド要素を挿入して構成する WSDL アサーションとポリシー アサーションを識別する。
ユーザー定義のバインドとバインド要素の作成については、「 User-Defined バインドの作成 」と「 BindingElement の作成」をそれぞれ参照してください。
構成サポートの追加
チャネルの構成ファイルのサポートを有効にするには、バインド要素の構成サポートを有効にする 2 つの構成セクション ( System.ServiceModel.Configuration.BindingElementExtensionElement) と、バインドの構成サポートを有効にする System.ServiceModel.Configuration.StandardBindingElement と System.ServiceModel.Configuration.StandardBindingCollectionElement<TStandardBinding,TBindingConfiguration>を実装する必要があります。
これを行う簡単な方法は、 ConfigurationCodeGenerator サンプル ツールを使用して、バインドとバインド要素の構成コードを生成することです。
BindingElementExtensionElement の拡張
次のコード例は、 トランスポート: UDP サンプルから取得します。
UdpTransportElement
は、構成システムにUdpTransportBindingElement
を公開するBindingElementExtensionElementです。 いくつかの基本的なオーバーライドを使用して、構成セクション名、バインド要素の型、およびバインド要素の作成方法を定義します。 その後、ユーザーは次のように拡張セクションを構成ファイルに登録できます。
<configuration>
<system.serviceModel>
<extensions>
<bindingElementExtensions>
<add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport" />
</bindingElementExtensions>
</extensions>
</system.serviceModel>
</configuration>
この拡張機能は、トランスポートとして UDP を使用するためにカスタム バインドから参照できます。
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding configurationName="UdpCustomBinding">
<udpTransport/>
</binding>
</customBinding>
</bindings>
</system.serviceModel>
</configuration>
バインドの構成の追加
SampleProfileUdpBindingCollectionElement
セクションは、構成システムにStandardBindingCollectionElement<TStandardBinding,TBindingConfiguration>を公開するSampleProfileUdpBinding
です。 実装の大部分は、SampleProfileUdpBindingConfigurationElement
から派生したStandardBindingElementに委任されます。
SampleProfileUdpBindingConfigurationElement
には、SampleProfileUdpBinding
のプロパティに対応するプロパティと、ConfigurationElement
バインドからマップする関数があります。 最後に、次のサンプル コードに示すように、 OnApplyConfiguration
メソッドは SampleProfileUdpBinding
でオーバーライドされます。
protected override void OnApplyConfiguration(string configurationName)
{
if (binding == null)
throw new ArgumentNullException("binding");
if (binding.GetType() != typeof(SampleProfileUdpBinding))
{
var expectedType = typeof(SampleProfileUdpBinding).AssemblyQualifiedName;
var typePassedIn = binding.GetType().AssemblyQualifiedName;
throw new ArgumentException($"Invalid type for binding. Expected type: {expectedType}. Type passed in: {typePassedIn}.");
}
SampleProfileUdpBinding udpBinding = (SampleProfileUdpBinding)binding;
udpBinding.OrderedSession = this.OrderedSession;
udpBinding.ReliableSessionEnabled = this.ReliableSessionEnabled;
udpBinding.SessionInactivityTimeout = this.SessionInactivityTimeout;
if (this.ClientBaseAddress != null)
udpBinding.ClientBaseAddress = ClientBaseAddress;
}
このハンドラーを構成システムに登録するには、関連する構成ファイルに次のセクションを追加します。
<configuration>
<configSections>
<sectionGroup name="system.serviceModel">
<sectionGroup name="bindings">
<section name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />
</sectionGroup>
</sectionGroup>
</configSections>
</configuration>
その後、 <system.serviceModel> 構成セクションから参照できます。
<configuration>
<system.serviceModel>
<client>
<endpoint configurationName="calculator"
address="soap.udp://localhost:8001/"
bindingConfiguration="CalculatorServer"
binding="sampleProfileUdpBinding"
contract= "Microsoft.ServiceModel.Samples.ICalculatorContract">
</endpoint>
</client>
</system.serviceModel>
</configuration>
バインド要素のメタデータ サポートの追加
チャネルをメタデータ システムに統合するには、ポリシーのインポートとエクスポートの両方をサポートする必要があります。 これにより、 ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe) などのツールで、バインド要素のクライアントを生成できます。
WSDL サポートの追加
バインディング内のトランスポート バインド要素は、メタデータ内のアドレス指定情報をエクスポートおよびインポートする役割を担います。 SOAP バインドを使用する場合は、トランスポート バインド要素もメタデータ内の正しいトランスポート URI をエクスポートする必要があります。 次のコード例は、 トランスポート: UDP サンプルから取得します。
WSDL エクスポート
アドレス指定情報をエクスポートするために、 UdpTransportBindingElement
は System.ServiceModel.Description.IWsdlExportExtension インターフェイスを実装します。
IWsdlExportExtension.ExportEndpointメソッドは、WSDL ポートに正しいアドレス指定情報を追加します。
if (context.WsdlPort != null)
{
AddAddressToWsdlPort(context.WsdlPort, context.Endpoint.Address, encodingBindingElement.MessageVersion.Addressing);
}
ExportEndpoint メソッドのUdpTransportBindingElement
実装では、エンドポイントが SOAP バインディングを使用する場合にもトランスポート URI がエクスポートされます。
WsdlNS.SoapBinding soapBinding = GetSoapBinding(context, exporter);
if (soapBinding != null)
{
soapBinding.Transport = UdpPolicyStrings.UdpNamespace;
}
WSDL インポート
アドレスのインポートを処理するように WSDL インポート システムを拡張するには、Svcutil.exe.config ファイルに示すように、Svcutil.exe の構成ファイルに次の構成を追加します。
<configuration>
<system.serviceModel>
<client>
<metadata>
<wsdlImporters>
<extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />
</wsdlImporters>
</metadata>
</client>
</system.serviceModel>
</configuration>
Svcutil.exeを実行する場合、Svcutil.exe に WSDL インポート拡張をロードさせるには、次の 2 つのオプションがあります。
/SvcutilConfig:<file> を使用して、構成ファイルをポイント Svcutil.exe。
設定セクションを Svcutil.exe.config と同じディレクトリに追加します Svcutil.exe。
UdpBindingElementImporter
型は、System.ServiceModel.Description.IWsdlImportExtension インターフェイスを実装します。
ImportEndpoint
メソッドは、WSDL ポートからアドレスをインポートします。
BindingElementCollection bindingElements = context.Endpoint.Binding.CreateBindingElements();
TransportBindingElement transportBindingElement = bindingElements.Find<TransportBindingElement>();
if (transportBindingElement is UdpTransportBindingElement)
{
ImportAddress(context);
}
ポリシーサポートの追加
カスタム バインド要素は、サービス エンドポイントの WSDL バインド内のポリシー アサーションをエクスポートして、そのバインド要素の機能を表現できます。 次のコード例は、 トランスポート: UDP サンプルから取得します。
ポリシーのエクスポート
UdpTransportBindingElement
型は、ポリシーのエクスポートのサポートを追加するSystem.ServiceModel.Description.IPolicyExportExtensionを実装します。 その結果、 System.ServiceModel.Description.MetadataExporter には、それを含むバインディングのポリシーの生成に UdpTransportBindingElement
が含まれます。
IPolicyExportExtension.ExportPolicyで、チャネルがマルチキャスト モードの場合は、UDP のアサーションと別のアサーションを追加します。 これは、マルチキャスト モードが通信スタックの構築方法に影響を与えるので、両側の間で調整する必要があるためです。
ICollection<XmlElement> bindingAssertions = context.GetBindingAssertions();
XmlDocument xmlDocument = new XmlDocument();
bindingAssertions.Add(xmlDocument.CreateElement(
UdpPolicyStrings.Prefix, UdpPolicyStrings.TransportAssertion, UdpPolicyStrings.UdpNamespace));
if (Multicast)
{
bindingAssertions.Add(xmlDocument.CreateElement(
UdpPolicyStrings.Prefix, UdpPolicyStrings.MulticastAssertion, UdpPolicyStrings.UdpNamespace));
}
カスタム・トランスポート・バインディング・エレメントはアドレス指定の処理を担当するため、UdpTransportBindingElement
上のSystem.ServiceModel.Description.IPolicyExportExtension実装では、使用されている WS-Addressing のバージョンを示す適切な WS-Addressing・ポリシー・アサーションのエクスポートも処理する必要があります。
AddWSAddressingAssertion(context, encodingBindingElement.MessageVersion.Addressing);
ポリシーのインポート
ポリシー インポート システムを拡張するには、Svcutil.exe.config ファイルに示すように、Svcutil.exe の構成ファイルに次の構成を追加します。
<configuration>
<system.serviceModel>
<client>
<metadata>
<policyImporters>
<extension type=" Microsoft.ServiceModel.Samples.UdpBindingElementImporter, UdpTransport" />
</policyImporters>
</metadata>
</client>
</system.serviceModel>
</configuration>
次に、登録されたクラス (UdpBindingElementImporter
) からSystem.ServiceModel.Description.IPolicyImportExtensionを実装します。
IPolicyImportExtension.ImportPolicyで、適切な名前空間のアサーションを調べ、トランスポートを生成してマルチキャストかどうかを確認するためのアサーションを処理します。 さらに、インポーターが処理するアサーションをバインディング アサーションの一覧から削除します。 ここでも、Svcutil.exeを実行する場合、統合には次の 2 つのオプションがあります。
/SvcutilConfig:<file>を使用して、構成ファイル Svcutil.exe ポイントします。
設定セクションを Svcutil.exe.config と同じディレクトリに追加します Svcutil.exe。
カスタム標準バインド インポーターの追加
Svcutil.exe と System.ServiceModel.Description.WsdlImporter の種類は、既定では、システム提供のバインドを認識してインポートします。 それ以外の場合、バインドは System.ServiceModel.Channels.CustomBinding インスタンスとしてインポートされます。 Svcutil.exe と WsdlImporter が SampleProfileUdpBinding
をインポートできるようにするために、 UdpBindingElementImporter
はカスタム標準バインディング インポーターとしても機能します。
カスタム標準バインド インポーターは、System.ServiceModel.Description.IWsdlImportExtension インターフェイスに ImportEndpoint
メソッドを実装して、メタデータからインポートされたSystem.ServiceModel.Channels.CustomBinding インスタンスを調べて、特定の標準バインドによって生成された可能性があるかどうかを確認します。
if (context.Endpoint.Binding is CustomBinding)
{
Binding binding;
if (transportBindingElement is UdpTransportBindingElement)
{
//if TryCreate is true, the CustomBinding will be replace by a SampleProfileUdpBinding in the
//generated config file for better typed generation.
if (SampleProfileUdpBinding.TryCreate(bindingElements, out binding))
{
binding.Name = context.Endpoint.Binding.Name;
binding.Namespace = context.Endpoint.Binding.Namespace;
context.Endpoint.Binding = binding;
}
}
}
一般に、カスタム標準バインド インポーターを実装するには、インポートされたバインド要素のプロパティを調べて、標準バインドによって設定された可能性があるプロパティのみが変更され、その他のすべてのプロパティが既定値であることを確認する必要があります。 標準バインド インポーターを実装するための基本的な方法は、標準バインドのインスタンスを作成し、バインド要素から標準バインドがサポートする標準バインド インスタンスにプロパティを伝達し、標準バインドのバインド要素をインポートされたバインド要素と比較することです。