はじめに
本稿は「The Baker’s Dozen」シリーズの一記事です。本稿では、リモーティングとリモーティングインターフェイスの概要を解説します。
.NETリモーティングを使用すると、マシンの物理的な境界の外側で実行されているコード(例えば、アプリケーションサーバー上のクラスにアクセスするWebサービスや、クライアント/サーバー環境の中間層にアクセスするクライアントアプリケーションなど)を呼び出して実行することができます。こうしたコードは、コードが置かれているドメインで実行されます。
リモーティングは、別のドメインにあるコードを実行するための理想的なアプローチです。リモーティングインターフェイスを使うことで、現在のプロジェクトの外側にある厳密に型指定されたモデルのコードにアクセスするプログラムを作成することができます。リモーティングソリューションの構築には工夫が必要なので、初めはWebサービスより複雑な感じを受けるかもしれません。そこで、本稿では、簡単なリモーティングプロジェクトを少しずつ説明しながらリモーティングを分かりやすく紹介します。まず、リモーティングアーキテクチャの概要とリモーティングのさまざまな使い方を説明してから、リモーティングの基本的な性質を詳しく説明します。また、Visual Studio 2005におけるリモーティングの新しい機能もいくつか紹介します。最後に、高度なリモーティングを解説しているWebサイトを紹介します。
目的
ここ数ヶ月間、私はVisual Studio 2005でのリモーティングに関する記事を書く予定でいたのですが、数週間前からリモーティングに直接関係するさまざまな質問をインターネットで目にしてきました。例えば、インターフェイスの実践的な使用に関する質問や、ジェネリックの価値に関する質問、リモーティングがWebサービスより好ましい理由についての質問などがありました。こうした質問はこの記事を書く刺激になりました。
私は1年半に渡り、「Baker's Dozen」シリーズで特定の技術や経験のある人を対象とした記事を書いてきました。今回紹介するヒントは次のとおりです。リモートアプリケーションの基礎知識と、インターフェイスの使い方を解説します。
- リモーティングアーキテクチャの概要
- リモーティングの実装オプション(TCPおよびHTTP)
- リモーティングインターフェイスを定義する
- リモーティングによってアクセスするビジネスオブジェクトを定義する
- クライアントサイドを定義する
- サーバー(リスナ)を定義する
- Visual Studio 2005でデータセットリモーティングのパフォーマンスを向上させる
- Windowsサービスを作成する
- Visual Studio 2005におけるTCPリモーティングの新しいセキュリティ強化
- Visual Studio 2005のジェネリックの概要
- ジェネリックを使ってリモーティングインターフェイスを簡易化する
- リモーティングオブジェクトファクトリを作成する
- リモーティングオブジェクトファクトリを使用する
Visual Studio 2005と特に明記されていない限り、これらのヒントの多くはVisual Studio 2003にも当てはまります。本稿の最後に、リモーティングに役立つ参考サイトを紹介します。では、始めましょう。
ヒント1:リモーティングアーキテクチャの概要
初めに非常に簡単な例を紹介しましょう。中間層(外部メソッド)にある別のクラスを呼び出す必要があるローカルクラス(クライアントクラス)があるとします。外部メソッドは顧客キーに基づいて顧客データを取得します。クライアントクラスとリモートメソッドは別々のアプリケーション境界にあるので、クライアントクラスは、外部メソッドが取得するデータがプロジェクトファイルなのか参照なのか分かりません。クライアントクラスが外部メソッドを実行する場合、外部メソッド内のコードは外部メソッドが置かれているドメインで実行しなければなりません。
最初は、リフレクションに使って外部メソッドを動的に検索して読み込もうと思うかもしれません。それも可能ですが、このアプローチを使うときは、モジュール、名前、場所などを指定できることが前提となります。
この問題を解決するには、呼び出し側のプロジェクトと外部メソッドの両方が使用できる厳密に型指定されたリモーティングインターフェイスを定義します。TCPリモーティングを使って、アプリケーション境界を越えて外部メソッドにアクセスします。厳密な型指定によるアプローチは効率性に優れ、ランタイムエラーが発生することもほとんどありません。
これを実行するステップをまとめると、次のようになります。
GetCustomer
メソッドの定義を入れる厳密に型指定されたインターフェイス(ICustomer
)を作成します。- 基本ビジネスオブジェクト(
BaseBzObject
)クラスを作成し、そこから外部メソッドを継承します。この基本ビジネスオブジェクトそのものはSystem.MarshalByRefObject
から継承します。これはリモーティングに必須のクラスです。 - 顧客ビジネスオブジェクト(
CustomerBzObject
)を作成します。このオブジェクトは、BaseBzObject
から継承し、ICustomer
を実装して、GetCustomer
メソッドを含める、という3つのことを行います。 - リスナを作成します。これは
CustomerBzObject
を登録するリモーティングサーバーです。クライアントクラスはTCPポートを介して登録されているクラスにアクセスし、アクティブ化することができます。 - 簡単なクライアントを作成します。このクライアントは、リモーティングサーバー/リスナがモニタする同じTCPポートを介して、
ICustomer
インターフェイスへの型参照を使ってオブジェクトをアクティブ化します。
以上5つのステップは、リモーティングで扱う「もの」を表します。リモーティングの「方法」と「理由」については、ヒント3~7で説明します。
ヒント2:リモーティングの実装オプション
リモーティングにはTCPとHTTPの2つの種類があります。これで、.NET Webサービスを追加するときの分散コンピューティングの選択肢は合計で3つになります。これらの実装は組み合わせることも可能で、例えば、クライアント層とアプリケーション層の間でWebサービスを使い、アプリケーション層の内側でリモーティングを使うことができます。
3つの実装オプションを使う一般的な理由は次のとおりです。
- ASP.NET Webサービスは、SOAP over HTTPをサポートしなければならない場合や、アプリケーションにアクセスするアプリケーションが.NET以外の場合に使います。
- HTTPリモーティングは、すべての層に必ず.NETを使うけれどもHTTPも利用しなければならないインストールシステム向けのオプションです。IIS下でリモーティングコンポーネントをセットアップして認証機能とセキュリティ機能を使うことができます。
- Visual Studio 2003のTCPリモーティングは、セキュリティを必要としない内部アプリケーションに最適のオプションでした。TCPリモーティングは通常は(厳密にはインスタンスによって異なりますが)3つの中で一番高速です。また、Visual Studio 2005では、セキュリティ機能を提供してTCPリモーティングを拡張しています(ヒント9を参照)。これにより、内部アプリケーション以外のアプリケーションにもTCPリモーティングを利用できるようになりました。
Visual Studio 2005ではリモーティングがさらに強化され、アプリケーション境界を越えてバイナリ形式でデータセットをシリアライズできるようになりました(ヒント7を参照)。これにより、データセットとXML文字列の間の変換をプログラミングする必要がなくなり、物理的な境界を越えて渡すデータセットのサイズが縮小されます。
ヒント3:リモーティングインターフェイスを作成する
ヒント1で説明したように、最初のステップはインターフェイスの作成です。アクセス先となる外部クラスがこのインターフェイスを実装します。クライアントはこのインターフェイスを使って外部クラスにアクセスします。
using System; using System.Text; using System.Data; namespace SimpleInterfaces { public interface ICustomer { DataSet GetCustomer(int AccountID); // we could have more, like a // SaveData method //void SaveData(DataSet CustomerData); } }
このインターフェイスのGetCustomer
メソッドには実際のコードが何も書かれていないことに注意してください。ここで大切な点は、このインターフェイスを実装するすべてのクラスはGetCustomer
というメソッドを持たなければならない、ということだけです。これは、アカウントID(AccountID
)を受け取ってデータセット(DataSet
)を返すメソッドです。詳しくは後で説明しますが、クライアントサイドに必要なのはこれだけです。