チャネル ファクトリとキャッシュ

WCF クライアント アプリケーションでは、ChannelFactory<TChannel> クラスを使用して WCF サービスとの通信チャネルを作成します。 ChannelFactory<TChannel> インスタンスを作成する場合は、次の操作が必要になるため、オーバーヘッドが生じます。

  • ContractDescription ツリーの構築

  • 必要なすべての CLR 型の反映

  • チャネル スタックの構築

  • リソースの破棄

このオーバーヘッドを最小限に抑えるために、WCF では、WCF クライアント プロキシの使用時にチャネル ファクトリをキャッシュできます。

ヒント

ChannelFactory<TChannel> クラスを直接使用する場合は、チャネル ファクトリの作成を直接制御できます。

ServiceModel メタデータ ユーティリティ ツール (Svcutil.exe) で生成された WCF クライアント プロキシは ClientBase<TChannel> から派生します。 ClientBase<TChannel> では、チャネル ファクトリのキャッシュ動作を定義する静的な CacheSetting プロパティを定義します。 キャッシュ設定は特定の型に対して行われます。 たとえば、ClientBase<ITest>.CacheSettings を以下に定義されているいずれかの値に設定すると、ITest 型のプロキシ/ClientBase にのみ影響します。 最初のプロキシ/ClientBase インスタンスが作成された時点で、特定の ClientBase<TChannel> のキャッシュ設定は不変になります。

キャッシュ動作の指定

キャッシュ動作は、CacheSetting プロパティを次のいずれかの値に設定することで指定します。

キャッシュの設定値 説明
AlwaysOn アプリケーション ドメイン内の ClientBase<TChannel> のすべてのインスタンスはキャッシュに参加できます。 開発者は、セキュリティがキャッシュに悪影響を与えないことを確認しています。 ClientBase<TChannel> の "セキュリティに影響する" プロパティに対してアクセスが生じても、キャッシュは無効になりません。 ClientBase<TChannel> の "セキュリティに影響する" プロパティは ClientCredentialsEndpointChannelFactory です。
Default 構成ファイルで定義されているエンドポイントから作成された ClientBase<TChannel> のインスタンスのみがアプリケーション ドメイン内のキャッシュに参加します。 そのアプリケーション ドメイン内にプログラムで作成された ClientBase<TChannel> のインスタンスはキャッシュに参加しません。 また、ClientBase<TChannel> の "セキュリティに影響する" プロパティに対してアクセスが生じると、そのインスタンスのキャッシュが無効になります。
AlwaysOff 対象となるアプリケーション ドメイン内にある特定の型の ClientBase<TChannel> のすべてのインスタンスのキャッシュが無効になります。

CacheSetting プロパティを使用する方法を次のコード スニペットに示します。

class Program
{
   static void Main(string[] args)
   {
      ClientBase<ITest>.CacheSettings = CacheSettings.AlwaysOn;
      foreach (string msg in messages)
      {
         using (TestClient proxy = new TestClient (new BasicHttpBinding(), new EndpointAddress(address)))
         {
            // ...
            proxy.Test(msg);
            // ...
         }
      }
   }
}
// Generated by SvcUtil.exe
public partial class TestClient : System.ServiceModel.ClientBase, ITest { }

上のコードでは、TestClient のすべてのインスタンスで同じチャネル ファクトリを使用します。

class Program
{
   static void Main(string[] args)
   {
      ClientBase<ITest>.CacheSettings = CacheSettings.Default;
      int i = 1;
      foreach (string msg in messages)
      {
         using (TestClient proxy = new TestClient ("MyEndpoint", new EndpointAddress(address)))
         {
            if (i == 4)
            {
               ServiceEndpoint endpoint = proxy.Endpoint;
               ... // use endpoint in some way
            }
            proxy.Test(msg);
         }
         i++;
   }
}

// Generated by SvcUtil.exe
public partial class TestClient : System.ServiceModel.ClientBase, ITest {}

上の例では、TestClient のすべてのインスタンスで同じチャネル ファクトリを使用します (インスタンス #4 を除く)。 インスタンス #4 では、そのインスタンス専用に作成されたチャネル ファクトリを使用します。 この設定は、特定のエンドポイントで同じチャネル ファクトリ型 (この場合は ITest) の他のエンドポイントと異なるセキュリティ設定が必要なシナリオに有効です。

class Program
{
   static void Main(string[] args)
   {
      ClientBase<ITest>.CacheSettings = CacheSettings.AlwaysOff;
      foreach (string msg in messages)
      {
         using (TestClient proxy = new TestClient ("MyEndpoint", new EndpointAddress(address)))
         {
            proxy.Test(msg);
         }
      }
   }
}

// Generated by SvcUtil.exe
public partial class TestClient : System.ServiceModel.ClientBase, ITest {}

上の例では、TestClient のすべてのインスタンスで異なるチャネル ファクトリを使用します。 これは、エンドポイントごとにセキュリティ要件が異なり、キャッシュする意味がない場合に便利です。

関連項目