新しい Web サービスの追加

提供: RAD Studio
移動先: 案内検索

Web サービスをサポートするサーバーの記述 への移動


新しい Web サービスのインターフェイスを、サーバー アプリケーションに追加するには、[ファイル|新規作成|その他...]を選択し、WebServices ページで、[SOAP サーバー インターフェイス]というラベルのアイコンをダブルクリックします。

[Web サービスの新規追加]ダイアログ ボックスで、クライアントに公開したい、呼び出し可能なインターフェイスの名前を指定すると、そのインターフェイスとその実装クラスを宣言および登録するためのコードが生成されます。 デフォルトで、ウィザードでは、サンプル メソッドとその他の型定義を示すコメントも生成されるため、生成されたファイルの編集に着手しやすくなっています。

生成されたコードの編集

生成されたユニットの interface セクションに現れるインターフェイス定義です。この生成されたユニットには、ウィザードを使用して指定した名前がつきます。インターフェイスの宣言を変更するには、サンプル メソッドを、クライアントが使用できるようにさせたいメソッドに変更します。

ウィザードは、Soap.InvokeRegistry.TInvokableClass を継承し、呼び出し可能インターフェイスをサポートする、実装クラスを生成します。呼び出し可能インターフェイスを 1 から定義する場合は、実装クラスの宣言を編集し、生成された呼び出し可能インターフェイスに対して行うあらゆる編集において、一致させなければなりません。

呼び出し可能インターフェイスおよび実装クラスへメソッドを追加する場合、そのメソッドではリモート可能な型のみ使用できる点に注意してください。リモート可能な型および呼び出し可能インターフェイスの詳細については、「呼び出し可能インターフェイスでの非スカラー型の使用」を参照してください。

異なる基底クラスの利用

WebService の新規追加ウィザードは、TInvokableClass を継承した実装クラスを生成します。 これが、Web サービスを実装する新規クラスを作成する、もっとも簡単な方法です。 ただし、この生成されたクラスを、異なる基底クラスを持つ実装クラスに置き換えることはできません(たとえば、既存のクラスを基底クラスとして使用することができます)。 生成された実装クラスを置き換える際には、次のようにいくつか考慮すべきポイントがあります:

  • 新しい実装クラスは、直接呼び出し可能インターフェイスをサポートしなければなりません。呼び出しレジストリ(呼び出し可能インターフェイスと実装クラスを登録する)は、どのクラスが、どの登録されたインターフェイスを実装しているのかを追跡し続け、呼び出し側がインターフェイスを呼び出さなければならなくなった際に、呼び出し側のコンポーネントに利用できるようにします。これは、インターフェイスがクラス宣言に直接含まれている場合には、クラスがインターフェイスを実装することを検知するのみです。基底クラスと共に継承されている場合には、インターフェイスのサポートは検知されません。
  • 新しい実装クラスは、IInterface メソッドに対するサポートを、インターフェイスの一部に含まなければなりません。このポイントは明らかなようで、簡単に見落としがちな点です。
  • 実装クラスのインスタンスを作成するファクトリ メソッドを含めるよう、実装クラスを登録する生成コードを変更しなければなりません。

この最後の点には、少し説明が必要でしょう。実装クラスが TInvokableClass を継承し、継承したコンストラクタを 1 つまたは複数のパラメータを持つ新しいコンストラクタに置き換えなかった場合、呼び出しレジストリは、必要に応じてクラスのインスタンスを作成する方法を知っています。TInvokableClass を継承していない実装クラスを記述した場合、または、コンストラクタを変更した場合、呼び出しレジストリに、実装クラスのインスタンスの取得方法を伝えなければなりません。

呼び出しレジストリに、実装クラスのインスタンスを取得する方法を、ファクトリのプロシージャを提供することで、伝えることができます。TInvokableClass から継承し、継承コンストラクタを使用する実装コンストラクタでも、ファクトリ プロシージャを用意したい場合もあるでしょう。たとえば、アプリケーションが呼び出し可能インターフェイスへの呼び出しを受け取るたびに、新しいインスタンスの作成を呼び出しレジストリに要求するのでなく、実装クラスの単一のグローバル インスタンスを使用することができます。

ファクトリ プロシージャは、型 TCreateInstanceProc でなければなりません。実装クラスのインスタンスを返します。プロシージャが新しいインスタンスを作成した場合、実装オブジェクトは、そのインターフェイスへの参照カウントが 0 になったときに解放しなければなりません。呼び出しレジストリは、明示的にオブジェクトのインスタンスを解放しないからです。次のコードでは別のアプローチを示しており、ファクトリ プロシージャが、実装クラスのグローバル インスタンスを 1 つ返します:

Delphi:

procedure CreateEncodeDecode(out obj: TObject);
begin
  if FEncodeDecode = nil then
  begin
    FEncodeDecode := TEncodeDecode.Create;
    {save a reference to the interface so that the global instance doesn't free itself }
    FEncodeDecodeInterface := FEncodeDecode as IEncodeDecode;
  end;
  obj := FEncodeDecode; { return global instance }
end;

C++:

void __fastcall CreateEncodeDecode(System::TObject* &obj)
{
  if (!FEncodeDecode)
  {
    FEncodeDecode = new TEncodeDecodeImpl();
    // save a reference to the interface so that the global instance doesn't free itself
TEncodeDecodeImpl->QueryInterface(FEncodeDecodeInterface);
}
obj = FEncodeDecode;
}

メモ: この例では、FEncodeDecodeInterface は、型 IEncodeDecode の変数です。

ファクトリ プロシージャを実装クラスと共に登録しますが、その際、クラスを呼び出しレジストリに登録する呼び出しの第 2 パラメータとして、ファクトリ プロシージャを渡します。まず、実装クラスを登録するため、ウィザードが生成した呼び出しを検索します。これは、クラスを定義するユニットの initialization セクションに現れます。次のような形になるでしょう:

Delphi:

InvRegistry.RegisterInvokableClass(TEncodeDecode);

C++:

InvRegistry()->RegisterInvokableClass(__classid(TEncodeDecodeImpl));

この呼び出しに、ファクトリ プロシージャを指定する第 2 パラメータを追加します:

Delphi:

InvRegistry.RegisterInvokableClass(TEncodeDecode, CreateEncodeDecode);

C++:

InvRegistry()->RegisterInvokableClass(__classid(TEncodeDecodeImpl), &CreateEncodeDecode);

関連項目