方法: カスタム ポリシー アサーションをインポートする

ポリシー アサーションはサービス エンドポイントの機能と要件を説明します。 クライアント アプリケーションはサービス メタデータにあるポリシー アサーションを使用して、クライアント バインディングを構成したり、サービス エンドポイントのサービス コントラクトをカスタマイズしたりできます。

カスタム ポリシー アサーションは、System.ServiceModel.Description.IPolicyImportExtension インターフェイスを実装して、このオブジェクトをメタデータ システムに渡すか、またはアプリケーション構成ファイルに実装型を登録することによってインポートします。 IPolicyImportExtension インターフェイスの実装は、パラメーターなしのコンストラクターを提供する必要があります。

カスタム ポリシー アサーションをインポートするには

  1. クラスに System.ServiceModel.Description.IPolicyImportExtension インターフェイスを実装します。 次の手順を参照してください。

  2. 次のいずれかの方法でカスタム ポリシー インポーターを挿入します。

  3. 構成ファイルを使用します。 次の手順を参照してください。

  4. ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe) で構成ファイルを使用します。 次の手順を参照してください。

  5. プログラムでポリシー インポーターを挿入します。 次の手順を参照してください。

任意のクラスに System.ServiceModel.Description.IPolicyImportExtension インターフェイスを実装するには

  1. IPolicyImportExtension.ImportPolicy メソッドで、対象となる各ポリシーについて、メソッドに渡された System.ServiceModel.Description.PolicyConversionContext オブジェクトで (必要となるアサーションのスコープに応じて) 適切なメソッドを呼び出すことにより、インポートする必要があるポリシー アサーションを見つけます。 次のコード例では、PolicyAssertionCollection.Remove メソッドを使用して、一度にカスタム ポリシー アサーションを見つけてコレクションから削除する方法を示します。 remove メソッドを使用してアサーションの検索と削除を行う場合は、手順 4. を実行する必要はありません。

    // Locate the custom assertion and remove it.
    XmlElement customAssertion = context.GetBindingAssertions().Remove(name1, ns1);
    if (customAssertion != null)
    {
      Console.WriteLine(
        "Removed our custom assertion from the imported "
        + "assertions collection and inserting our custom binding element."
      );
      // Here we would add the binding modification that implemented the policy.
      // This sample does not do this.
      Console.ForegroundColor = ConsoleColor.Red;
      Console.WriteLine(customAssertion.NamespaceURI + " : " + customAssertion.Name);
      Console.WriteLine(customAssertion.OuterXml);
      Console.ForegroundColor = ConsoleColor.Gray;
    }
    
    ' Locate the custom assertion and remove it.
    Dim customAssertion As XmlElement = context.GetBindingAssertions().Remove(name1, ns1)
    If customAssertion IsNot Nothing Then
        Console.WriteLine("Removed our custom assertion from the imported " & "assertions collection and inserting our custom binding element.")
        ' Here we would add the binding modification that implemented the policy.
        ' This sample does not do this.
        Console.ForegroundColor = ConsoleColor.Red
        Console.WriteLine(customAssertion.NamespaceURI & " : " & customAssertion.Name)
        Console.WriteLine(customAssertion.OuterXml)
        Console.ForegroundColor = ConsoleColor.Gray
    End If
    
  2. ポリシー アサーションを処理します。 ポリシー システムでは、入れ子になったポリシーと wsp:optional を正規化しないので注意してください。 これらの構造体については、ポリシー インポート拡張機能の実装で処理する必要があります。

  3. ポリシー アサーションで指定されている機能または要件をサポートするバインディングまたはコントラクトのカスタマイズを実行します。 アサーションでは、通常、バインディングに特定の構成、または特定のバインド要素が必要です。 PolicyConversionContext.BindingElements プロパティにアクセスすることで、これらの変更を実行します。 これとは別に、コントラクトの変更が必要なアサーションがあります。 コントラクトへのアクセスと変更には、PolicyConversionContext.Contract プロパティを使用します。 ポリシー代替手段のインポートに失敗した場合、バインディングとコントラクトは同じなのに、ポリシー代替手段が異なるために、ポリシー インポーターが複数回呼び出されることがあるので注意してください。 作成するコードでは、この動作に対応する必要があります。

  4. アサーション コレクションからカスタム ポリシー アサーションを削除します。 アサーションを削除しない場合、Windows Communication Foundation (WCF) は、ポリシーのインポートが失敗して、関連付けられているバインディングがインポートされていないと見なします。 PolicyAssertionCollection.Remove メソッドを使用して、カスタム ポリシー アサーションの検索とコレクションからの削除を一度に行う場合は、この手順を実行する必要はありません。

構成ファイルを使用してメタデータ システムにカスタム ポリシー インポーターを挿入するには

  1. クライアント構成ファイルの <policyImporters> 要素内の <extensions> 要素にインポーター型を追加します。

    <client>
        <endpoint 
          address="http://localhost:8080/StatefulService" 
          binding="wsHttpBinding"
          bindingConfiguration="CustomBinding_IStatefulService" 
          contract="IStatefulService"
          name="CustomBinding_IStatefulService" />
      <metadata>
        <policyImporters>
          <extension type="Microsoft.WCF.Documentation.CustomPolicyImporter, PolicyExtensions"/>
        </policyImporters>
      </metadata>
    </client>
    
  2. クライアント アプリケーションで、System.ServiceModel.Description.MetadataResolver または System.ServiceModel.Description.WsdlImporter を使用してメタデータを解決すると、インポーターが自動的に呼び出されます。

    // Download all metadata.
    ServiceEndpointCollection endpoints
      = MetadataResolver.Resolve(
        typeof(IStatefulService),
        new EndpointAddress("http://localhost:8080/StatefulService/mex")
      );
    
    ' Download all metadata. 
    Dim endpoints As ServiceEndpointCollection = MetadataResolver.Resolve(GetType(IStatefulService), New EndpointAddress("http://localhost:8080/StatefulService/mex"))
    

Svcutil.exe を使用してメタデータ システムにカスタム ポリシー インポーターを挿入するには

  1. Svcutil.exe.config 構成ファイルの <policyImporters> 要素内の <extensions> 要素にインポーター型を追加します。 また、/svcutilConfig オプションを使用して、異なる構成ファイルに登録されているポリシー インポーター型を読み込むように Svcutil.exe を指定することもできます。

  2. ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe) を使用してメタデータをインポートすると、インポーターが自動的に呼び出されます。

プログラム使用してメタデータ システムにカスタム ポリシー インポーターを挿入するには

  1. メタデータをインポートする前に、インポーターを MetadataImporter.PolicyImportExtensions プロパティに追加します (たとえば、System.ServiceModel.Description.WsdlImporter を使用している場合)。

関連項目