次の方法で共有


ServiceHostFactory を使用したホストの拡張

WCF アーキテクチャを拡張するためのインターフェイスとして、Windows Communication Foundation (WCF) には、ホスティング サービスを実装するための標準 API である ServiceHost があります。ユーザーは、この ServiceHost の派生型として独自のホスト クラスを定義できます。通常は、ServiceDescription を使用するために OnOpening をオーバーライドして、これにより、サービスを開く前に、強制的に既定のエンドポイントを追加したり、動作を変更することができます。

自己ホスト環境では、カスタムの ServiceHost を作成する必要はありません。ホストをインスタンス化し、インスタンス化の後で Open を呼び出すコードを記述するので、この 2 つのステップの間に任意の処理を記述できます。たとえば、新しい IServiceBehavior を次のように追加できます。

public static void Main()
{
   ServiceHost host = new ServiceHost( typeof( MyService ) );
   host.Description.Add( new MyServiceBehavior() );
   host.Open();
   
   ...
}

この方法は再利用できません。説明を操作するコードはホスト プログラム (この場合は Main() 関数) に記述されているので、このロジックを別のコンテキストで使用するのは困難です。このような強制コードを記述することなく、IServiceBehavior を追加する方法もあります。ServiceBehaviorAttribute から派生した属性をサービス実装型に組み込む方法や、カスタム動作の詳細を構成できるようにしておき、構成を使用して動的に組み込む方法が考えられます。

ただし、サンプル コードを少し修正して問題を解決することもできます。1 つの方法として、ServiceBehavior を追加するコードを Main() 内に記述する代わりに、ServiceHost から派生した OnOpening メソッドに記述することができます。

public class DerivedHost : ServiceHost
{
   public DerivedHost( Type t, params Uri baseAddresses ) :
      base( t, baseAddresses ) {}
      
   public override void OnOpening()
   {
  this.Description.Add( new MyServiceBehavior() );
   }
}

Main() 内には、次のように記述できます。

public static void Main()
{
   ServiceHost host = new DerivedHost( typeof( MyService ) );
   host.Open();
   
   ...
}

このようにカスタム ロジックをカプセル化、抽象化すると、さまざまなホスト アプリケーションで再利用できます。

カスタムの ServiceHost を Internet Information Services (IIS) や Windows Process Activation Service (WAS) で使用する方法は、それほど単純ではありません。アプリケーションの代わりにホスティング環境が ServiceHost をインスタンス化するという点で、これらの環境は、自己ホスト環境と異なっています。IIS および WAS ホスティング インフラストラクチャは、ServiceHost のカスタム派生物については何も認識しません。

ServiceHostFactory は、独自に定義した ServiceHost の派生クラスに、IIS または WAS からアクセスする手段として設計されました。ServiceHost から派生したカスタム ホストは、動的に構成され、種類もさまざまであるため、ホスト環境でこれを直接インスタンス化することはありません。代わりに、WCF は "ファクトリ パターン" を使用して、ホスティング環境と、サービスの具体的な型との間に、間接レイヤを提供します。特に指定しなければ、ServiceHost のインスタンスを返す、ServiceHostFactory の既定の実装が使用されます。ただし、派生ホストを返す独自のファクトリを用意し、そのファクトリの CLR 型名を @ServiceHost ディレクティブで指定することもできます。

基本的なケースでは、独自のファクトリは容易に実装できます。派生 ServiceHost を返す、カスタムの ServiceHostFactory の例を次に示します。

public class DerivedFactory : ServiceHostFactory
{
   public override ServiceHost CreateServiceHost( Type t, Uri[] baseAddresses )
   {
      return new DerivedHost( t, baseAddresses )
   }
}

既定のファクトリの代わりにこのファクトリを使用するには、@ServiceHost ディレクティブに、次のように型名を記述します。

<% @ServiceHost Factory=”DerivedFactory” Service=”MyService” %>

CreateServiceHost から返す ServiceHost で行う処理について、技術的には制限はありませんが、ファクトリ実装はできるだけ単純にしておくことをお勧めします。カスタム ロジックが多い場合は、ファクトリ内ではなくホスト側に記述するようにして、ファクトリは再利用できるようにしておきます。

ここで、ホスティング API にはもう 1 つのレイヤがあることを知っておく必要があります。WCF には、ServiceHostBase および ServiceHostFactoryBase というクラスもあり、ServiceHostServiceHostFactory のそれぞれは、これらのクラスから派生しています。これらは、メタデータ システムの大部分がカスタム コードに置き換わるような、高度なシナリオを想定して用意されています。