次の方法で共有


動作を使用したランタイムの構成と拡張

動作を使用すると、既定の動作を変更したり、サービス構成を検査して検証したり、Windows Communication Foundation (WCF) クライアントおよびサービス アプリケーションのランタイム動作を変更したりするカスタム拡張機能を追加できます。 このトピックでは、動作インターフェイス、それらを実装する方法、およびサービスの説明 (サービス アプリケーション内) またはエンドポイント (クライアント アプリケーション内) にプログラムまたは構成ファイルで追加する方法について説明します。 システム提供の動作の使用方法の詳細については、「 サービス Run-Time 動作の指定 」および「 クライアント Run-Time 動作の指定」を参照してください。

動作

動作の種類は、WCF サービスまたは WCF クライアントを実行するランタイムを作成するために Windows Communication Foundation (WCF) によって使用される前に、サービスまたはサービス エンドポイント記述オブジェクト (サービスまたはクライアント上) に追加されます。 これらの動作がランタイム構築プロセス中に呼び出されると、コントラクト、バインディング、およびアドレスによって構築されたランタイムを変更するランタイム プロパティとメソッドにアクセスできるようになります。

行動方法

すべての動作には、 AddBindingParameters メソッド、 ApplyDispatchBehavior メソッド、 Validate メソッド、および 1 つの例外がある ApplyClientBehavior メソッドがあります。 IServiceBehavior はクライアントで実行できないため、 ApplyClientBehaviorは実装されません。

  • AddBindingParameters メソッドを使用して、ランタイムの作成時にカスタム バインドがアクセスできるカスタム オブジェクトをコレクションに変更または追加します。 たとえば、チャネルの構築方法に影響を与えるが、チャネル開発者には認識されない保護要件を指定する方法です。

  • Validate メソッドを使用して、説明ツリーと対応するランタイム オブジェクトを調べて、一部の条件セットに準拠していることを確認します。

  • ApplyDispatchBehaviorメソッドとApplyClientBehaviorメソッドを使用して、説明ツリーを調べ、サービスまたはクライアントの特定のスコープのランタイムを変更します。 拡張オブジェクトを挿入することもできます。

    これらのメソッドには説明ツリーが用意されていますが、これは検査専用です。 説明ツリーが変更された場合、動作は未定義です。

変更できるプロパティと実装できるカスタマイズ インターフェイスには、サービス およびクライアント ランタイム クラスを介してアクセスします。 サービスの種類は、 DispatchRuntime クラスと DispatchOperation クラスです。 クライアントの種類は、 ClientRuntime クラスと ClientOperation クラスです。 ClientRuntimeクラスとDispatchRuntime クラスは、クライアント全体およびサービス全体のランタイム プロパティと拡張コレクションにそれぞれアクセスするための拡張エントリ ポイントです。 同様に、 ClientOperation クラスと DispatchOperation クラスでは、クライアント操作とサービス操作のランタイム プロパティと拡張コレクションがそれぞれ公開されます。 ただし、必要に応じて、操作ランタイム オブジェクトからより広い範囲のランタイム オブジェクトにアクセスできます。

クライアントの実行動作を変更するために使用できるランタイム プロパティと拡張機能の種類については、「クライアントの 拡張」を参照してください。 サービス ディスパッチャーの実行動作を変更するために使用できるランタイム プロパティと拡張機能の種類については、「 ディスパッチャーの拡張」を参照してください。

ほとんどの WCF ユーザーは、ランタイムと直接対話しません。代わりに、エンドポイント、コントラクト、バインディング、アドレス、および構成ファイル内のクラスまたは動作に対する動作属性などのコア プログラミング モデルコンストラクトを使用します。 これらのコンストラクトは 、説明ツリーを構成します。これは、説明ツリーによって記述されたサービスまたはクライアントをサポートするランタイムを構築するための完全な仕様です。

WCF には、次の 4 種類の動作があります。

  • サービスの動作 (IServiceBehavior の種類) を使用すると、 ServiceHostBaseを含むサービス ランタイム全体をカスタマイズできます。

  • エンドポイントの動作 (IEndpointBehavior の種類) を使用すると、サービス エンドポイントとそれに関連付けられている EndpointDispatcher オブジェクトをカスタマイズできます。

  • コントラクト動作 (IContractBehavior 型) を使用すると、クライアント アプリケーションとサービス アプリケーションの ClientRuntime クラスと DispatchRuntime クラスの両方をカスタマイズできます。

  • 操作の動作 (IOperationBehavior の種類) を使用すると、 ClientOperation クラスと DispatchOperation クラスをクライアントとサービスでカスタマイズできます。

これらの動作をさまざまな説明オブジェクトに追加するには、カスタム属性を実装するか、アプリケーション構成ファイルを使用するか、適切な説明オブジェクトの behaviors コレクションに直接追加します。 ただし、ICommunicationObject.OpenまたはServiceHostChannelFactory<TChannel>を呼び出す前に、サービス記述またはサービス エンドポイント記述オブジェクトに追加する必要があります。

挙動スコープ

4 つの動作の種類があり、それぞれランタイム アクセスの特定のスコープに対応します。

サービスの動作

IServiceBehaviorを実装するサービス動作は、サービス ランタイム全体を変更する主要なメカニズムです。 サービスにサービス動作を追加するには、3 つのメカニズムがあります。

  1. サービス クラスでの属性の使用。 ServiceHostが構築されると、ServiceHost実装ではリフレクションを使用して、サービスの種類の属性のセットが検出されます。 これらの属性のいずれかが IServiceBehaviorの実装である場合は、 ServiceDescriptionの behaviors コレクションに追加されます。 これにより、これらの動作がサービスのランタイムの構築に参加できるようになります。

  2. プログラムによって、 ServiceDescriptionの behaviors コレクションに動作を追加します。 これを行うには、次のコード行を使用します。

    ServiceHost host = new ServiceHost(/* Parameters */);  
    host.Description.Behaviors.Add(/* Service Behavior */);  
    
  3. 構成を拡張するカスタム BehaviorExtensionElement の実装。 これにより、アプリケーション構成ファイルからのサービス動作を使用できます。

WCF のサービス動作の例としては、 ServiceBehaviorAttribute 属性、 ServiceThrottlingBehaviorServiceMetadataBehavior 動作などがあります。

コントラクトの動作

IContractBehavior インターフェイスを実装するコントラクト動作は、コントラクト全体でクライアントランタイムとサービス ランタイムの両方を拡張するために使用されます。

コントラクトにコントラクトの動作を追加するには、2 つのメカニズムがあります。 最初のメカニズムは、コントラクト インターフェイスで使用するカスタム属性を作成することです。 コントラクト インターフェイスが ServiceHost または ChannelFactory<TChannel>に渡されると、WCF はインターフェイスの属性を調べます。 属性が IContractBehavior の実装である場合、それらの属性は、そのインターフェイス用に作成された System.ServiceModel.Description.ContractDescription のビヘイビアー コレクションに追加されます。

カスタム コントラクト動作属性に System.ServiceModel.Description.IContractBehaviorAttribute を実装することもできます。 この場合、適用されると動作は次のようになります。

•コントラクト インターフェイス。 この場合、動作はエンドポイント内のその型のすべてのコントラクトに適用され、WCF は IContractBehaviorAttribute.TargetContract プロパティの値を無視します。

•サービス クラス。 この場合、動作は、コントラクトが TargetContract プロパティの値であるエンドポイントにのみ適用されます。

•コールバック クラスに適用した場合。 この場合、動作は双方向クライアントのエンドポイントに適用され、WCF は TargetContract プロパティの値を無視します。

2 つ目のメカニズムは、 ContractDescriptionの behaviors コレクションに動作を追加することです。

WCF のコントラクト動作の例には、 System.ServiceModel.DeliveryRequirementsAttribute 属性が含まれます。 詳細と例については、リファレンス トピックを参照してください。

エンドポイントの動作

IEndpointBehaviorを実装するエンドポイント動作は、特定のエンドポイントのサービス全体またはクライアントの実行時間を変更する主要なメカニズムです。

サービスにエンドポイントの動作を追加するには、2 つのメカニズムがあります。

  1. Behaviors プロパティに動作を追加します。

  2. 構成を拡張するカスタム BehaviorExtensionElement を実装します。

詳細と例については、リファレンス トピックを参照してください。

操作動作

IOperationBehavior インターフェイスを実装する操作動作は、各操作のクライアントランタイムとサービス ランタイムの両方を拡張するために使用されます。

操作に動作の特性を追加するには、2つのメカニズムがあります。 最初のメカニズムは、操作をモデル化するメソッドで使用するカスタム属性を作成することです。 操作がServiceHostまたはChannelFactoryに追加されると、WCF は、その操作用に作成されたIOperationBehaviorの動作コレクションにOperationDescription属性を追加します。

2 つ目のメカニズムは、構築された OperationDescriptionの behaviors コレクションに動作を直接追加することです。

WCF での操作動作の例としては、 OperationBehaviorAttributeTransactionFlowAttributeがあります。

詳細と例については、リファレンス トピックを参照してください。

構成を使用して動作を作成する

サービスとエンドポイント、およびコントラクトの動作は、コードで指定するか、属性を使用するように設計できます。アプリケーションまたは Web 構成ファイルを使用して構成できるのは、サービスとエンドポイントの動作のみです。 属性を使用して動作を公開すると、開発者はコンパイル時に実行時に追加、削除、または変更できない動作を指定できます。 これは多くの場合、サービスの正しい操作に常に必要な動作 (たとえば、 System.ServiceModel.ServiceBehaviorAttribute 属性に対するトランザクション関連のパラメーター) に適しています。 構成を使用して動作を公開すると、開発者はそれらの動作の仕様と構成をサービスをデプロイするユーザーに任せることができます。 これは、オプションコンポーネントやその他のデプロイ固有の構成 (メタデータがサービスに対して公開されているか、サービスの特定の承認構成に公開されるかなど) の動作に適しています。

また、構成をサポートする動作を使用して、会社のアプリケーション ポリシーを machine.config 構成ファイルに挿入し、それらの項目をロックダウンすることで、会社のアプリケーション ポリシーを適用することもできます。 説明と例については、「 方法: エンタープライズでエンドポイントをロックダウンする」を参照してください。

構成を使用して動作を公開するには、開発者は BehaviorExtensionElement の派生クラスを作成し、その拡張機能を構成に登録する必要があります。

次のコード例は、 IEndpointBehaviorBehaviorExtensionElementを実装する方法を示しています。

// BehaviorExtensionElement members  
public override Type BehaviorType  
{  
  get { return typeof(EndpointBehaviorMessageInspector); }  
}  
  
protected override object CreateBehavior()  
{  
  return new EndpointBehaviorMessageInspector();  
}  

構成システムがカスタム BehaviorExtensionElementを読み込むには、拡張機能として登録する必要があります。 次のコード例は、上記のエンドポイント動作の構成ファイルを示しています。

<configuration>  
  <system.serviceModel>  
    <services>  
      <service
        name="Microsoft.WCF.Documentation.SampleService"  
        behaviorConfiguration="metadataSupport"  
      >  
        <host>  
          <baseAddresses>  
            <add baseAddress="http://localhost:8080/ServiceMetadata" />  
          </baseAddresses>  
        </host>  
        <endpoint  
          address="/SampleService"  
          binding="wsHttpBinding"  
          behaviorConfiguration="withMessageInspector"
          contract="Microsoft.WCF.Documentation.ISampleService"  
        />  
        <endpoint  
           address="mex"  
           binding="mexHttpBinding"  
           contract="IMetadataExchange"  
        />  
      </service>  
    </services>  
    <behaviors>  
      <serviceBehaviors>  
      <behavior name="metadataSupport">  
        <serviceMetadata httpGetEnabled="true" httpGetUrl=""/>  
      </behavior>  
      </serviceBehaviors>  
      <endpointBehaviors>  
        <behavior name="withMessageInspector">  
          <endpointMessageInspector />  
        </behavior>  
      </endpointBehaviors>  
    </behaviors>  
    <extensions>  
      <behaviorExtensions>  
        <add
          name="endpointMessageInspector"  
          type="Microsoft.WCF.Documentation.EndpointBehaviorMessageInspector, HostApplication, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"  
        />  
      </behaviorExtensions>  
    </extensions>  
  </system.serviceModel>  
</configuration>  

ここで、 Microsoft.WCF.Documentation.EndpointBehaviorMessageInspector は動作拡張型で、 HostApplication はそのクラスがコンパイルされたアセンブリの名前です。

評価順序

System.ServiceModel.ChannelFactory<TChannel>System.ServiceModel.ServiceHostは、プログラミング モデルと説明からランタイムを構築する役割を担います。 前述のように、動作は、サービス、エンドポイント、コントラクト、および操作でそのビルド プロセスに貢献します。

ServiceHostは、次の順序で動作を適用します。

  1. サービス

  2. コントラクト

  3. エンドポイント

  4. オペレーション

動作のコレクション内では、順序は保証されません。

ChannelFactory<TChannel>は、次の順序で動作を適用します。

  1. コントラクト

  2. エンドポイント

  3. オペレーション

動作のコレクション内では、順序は保証されません。

プログラムによる動作の追加

サービス アプリケーションのSystem.ServiceModel.Description.ServiceDescriptionのプロパティは、CommunicationObject.OnOpeningSystem.ServiceModel.ServiceHostBase メソッドの後で変更しないでください。 ServiceHostBase.CredentialsAddServiceEndpointServiceHostBase プロパティやSystem.ServiceModel.ServiceHost メソッドなど、一部のメンバーは、その時点を過ぎて変更された場合に例外をスローします。 他の項目は変更可能ですが、結果は未定義です。

同様に、クライアントでは、System.ServiceModel.Description.ServiceEndpointOnOpeningを呼び出した後に、System.ServiceModel.ChannelFactory値を変更することはできません。 ChannelFactory.Credentials プロパティは、その時点を過ぎて変更した場合に例外をスローしますが、他のクライアント記述値はエラーなしで変更できます。 ただし、結果は未定義です。

サービスでもクライアントでも、 CommunicationObject.Openを呼び出す前に説明を変更することをお勧めします。

動作属性の継承規則

サービスの動作とコントラクトの動作という 4 種類の動作はすべて、属性を使用して設定できます。 属性はマネージド オブジェクトとメンバーで定義され、マネージド オブジェクトとメンバーは継承をサポートするため、継承のコンテキストで動作属性がどのように機能するかを定義する必要があります。

大まかに言うと、特定のスコープ (サービス、コントラクト、操作など) に対して、そのスコープの継承階層内のすべての動作属性が適用されます。 同じ型の 2 つの動作属性がある場合は、最も派生した型のみが使用されます。

サービスの動作

特定のサービス クラスの場合、そのクラスとそのクラスの親に対するすべてのサービス動作属性が適用されます。 継承階層内の複数の場所で同じ種類の属性が適用されている場合は、最も派生した型が使用されます。

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]  
[AspNetCompatibilityRequirementsAttribute(  
    AspNetCompatibilityRequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]  
public class A { /* … */ }  
  
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
public class B : A { /* … */}  

たとえば、前の例では、サービス B は、InstanceContextModeSingleAspNetCompatibilityRequirementsModeモードがAllowedConcurrencyModeSingleになります。 ConcurrencyModeSingle になるのは、サービス B の ServiceBehaviorAttribute 属性の方がサービス A よりも多く派生されているためです。

コントラクトの動作

特定のコントラクトに対して、そのインターフェイスとそのインターフェイスの親に対するすべてのコントラクト動作属性が適用されます。 継承階層内の複数の場所で同じ種類の属性が適用されている場合は、最も派生した型が使用されます。

操作動作

特定の操作が既存の抽象操作または仮想操作をオーバーライドしない場合、継承規則は適用されません。

操作が既存の操作をオーバーライドすると、その操作とその操作の親に対するすべての操作動作属性が適用されます。 継承階層内の複数の場所で同じ種類の属性が適用されている場合は、最も派生した型が使用されます。