.NET での COM+ サービスの使用

 

Tim McCarthy、InterKnowlogy
Paul D. Sheriff, PDSA, Inc.

2002 年 2 月

概要: 既存の COM および COM+ アプリケーションに新しい Microsoft .NET コンポーネントを追加すると、連携できるようになります。これは、トランザクションへの参加、ロールベースのセキュリティの活用、キューとの対話などを行うことができる .NET アプリケーションを開発する必要がある場合に役立ちます。 (14ページ印刷)

目標

  • Microsoft® .NET での COM+ サービスの使用について説明します。
  • サービス コンポーネントを作成します。
  • サービス コンポーネントをデプロイします。

前提条件

このドキュメントを最大限に活用するには、次のことが当てはまります。

  • Microsoft Visual Basic® 6.0 で Microsoft Transaction Server (MTS) と分散トランザクションを使用しました。
  • COM+ サービスでロールベースのセキュリティを使用しました。
  • COM+ サービスでキューを作成して使用しました。
  • .NET クラスに精通しています。
  • .NET でのコンソール アプリケーションの作成に慣れている。

内容

.NET での COM+ サービスの使用
Transaction-Based コンポーネントの開発
ロール ベース セキュリティ
キューに登録されたコンポーネントの使用
Visual Basic 6.0 以降の COM+ の変更点
まとめ

.NET での COM+ サービスの使用

おそらく、COM+ アプリケーションを使用して、Visual Basic または C++ で記述したコンポーネントをホストしました。 COM+ には、トランザクション、キューに登録されたコンポーネント、Just-In-Time のアクティブ化、ロールベースのセキュリティ、共有プロパティなど、多くの重要なサービスが用意されています。COM+ を使用してコンポーネントをホストするメインの魅力の 1 つは、コンポーネントのトランザクション サポートを必須としてマークするなど、コードを記述しなくてもコンポーネントの動作方法を変更できることです。 コンポーネント サービス MMC スナップイン内から COM+ コンポーネントにラジオ ボタンを設定すると、コンポーネントが作成されるたびに、COM+ トランザクションのコンテキストで作成されます。 コンポーネントで COM+ トランザクションが使用されている場合、すべてのデータベース トランザクションは分散トランザクション コーディネーター (DTC) によって処理されます。 図 1 は、コンポーネント サービス インターフェイス内から [必須トランザクション] オプションを設定する例を示しています。

図 1. トランザクションを必要とするサンプル COM+ コンポーネント

コンポーネントのセキュリティの設定は、トランザクション サポートを設定するのと同じくらい簡単です。 コードを再コンパイルすることなく、どのユーザーがどのコンポーネントを実行でき、どのメソッドを実行できるかを選択できます。 COM+ サービス スナップインを使用して選択します。

.NET ではすべての COM+ サービスを使用できます

.NET Frameworkでは、クラスが System.EnterpriseServices.ServicedComponent クラスから派生している限り、COM+ が提供するすべてのサービスを引き続き使用できます。 ServiceComponent クラスから派生したクラスは、COM+ サービスによってホストされ、使用可能な COM+ サービスのいずれかを使用できます。 表 1 に、.NET でサポートされているすべての COM+ サービスと、各サービスの簡単な説明を示します。

表 1 利用可能な COM+ サービス

COM+ サービス 説明
トランザクションの自動処理 宣言型トランザクション処理機能を適用します
COM トランザクション インテグレーター (COMTI) 自動化オブジェクトに CICS および IMS アプリケーションをカプセル化する
Resource Manager (CRM) の補正 非トランザクション リソースに原子性と持続性のプロパティを適用します
Just-In-Time ライセンス認証 メソッド呼び出しでオブジェクトをアクティブ化し、呼び出しが返されたときに非アクティブ化します
疎結合イベント オブジェクトベースのイベントを管理します
オブジェクトの構築 インスタンスの構築時にクラス インスタンスに永続的な文字列値を渡します
オブジェクト プール 既製のオブジェクトのプールを提供します
キューに入ったコンポーネント 非同期メッセージ キューを提供します
ロール ベース セキュリティ ロールに基づいてセキュリティ アクセス許可を適用します
共有プロパティ サーバー プロセス内の複数のオブジェクト間で状態を共有する
同期 (アクティビティ) コンカレンシーを管理します
XA 相互運用性 X/Open トランザクション処理モデルをサポート

.NET で COM+ サービスを使用する理由

トランザクションへの参加、ロールベースのセキュリティの活用、キューの操作などを行うことができる必要がある .NET アプリケーションを作成する場合は、.NET で提供される COM+ サービスを使用します。 .NET を使用すると、このドキュメントで学習するように、これらのサービスを簡単に実装できます。

**ヒント **COM+ サービスを操作するために .NET コードが必要ない場合、つまり、.NET Frameworkでのみ作業する予定の場合は、パフォーマンスが低下するため、System.EnterpriseServices を使用しないでください。

COM+ コンポーネント開発の概要

COM+ Services と対話するコンポーネントを .NET で作成する場合は、次の手順を実行します。 表 2 に、各ステップの説明を示します。

  1. クラス ライブラリを作成します。

  2. すべてのクラスを作成して、System.EnterpriseServices.ServicedComponents クラスから継承します。

  3. アセンブリを作成します。

  4. 厳密な名前を作成します。

    表 2 .NET コンポーネントの作成に使用される用語の定義

    用語 説明
    クラス ライブラリ クラスを含む.dll プロジェクトの種類。 通常、この種類のプロジェクトを使用するユーザー インターフェイスはありません。
    System.EnterpriseServices.ServicedComponents COM+ サービスと対話するために必要な.NET Framework内のクラス
    アセンブリ プロジェクト内のすべてのクラスとインターフェイスの説明
    厳密な名前 コンポーネントを COM+ サービスに登録できるように、アセンブリから GUID を生成します

Transaction-Based コンポーネントの開発

このドキュメントの最初の部分では、COM+ のトランザクション サービスを使用する .NET コンポーネントを作成する方法について説明します。 このコンポーネントと対話するコンポーネントとフロントエンド アプリケーションの両方を記述する方法について説明します。

COM+ トランザクション コンポーネントの作成

COM+ サービスで実行する .NET コンポーネントを取得するには、いくつかの手順を実行する必要があります。 まず、System.EnterpriseServices.ServicedComponent クラスから派生するクラスを作成する必要があります。 この基本クラスは、COM+ サービスと対話するために必要なすべての適切なメソッドとプロパティを提供します。 クラスを新しいトランザクションを要求するものとしてマークし、エラーが発生しなかった場合にトランザクションを自動的に完了できるように作成するメソッドをマークする必要があります。 試してみましょう。

  1. Microsoft Visual Studio® .NET を開き、ClassLibrary プロジェクトとして新しいプロジェクトを作成します。

  2. Class1.vb ファイルの名前を COMPlusServices.vb に変更します。

  3. COMPlusServices.vb ファイルを開き、クラス名を Class1 から COMPlusServices に変更します。

  4. 次に示すコードをこの新しいクラスに入力します。

    Imports System.EnterpriseServices
    Imports System.Reflection
    
    '********************************************
    'COM+ Registration details 
    
    'Supply the COM+ application name 
    <Assembly: ApplicationNameAttribute("ComPlusExample")> 
    
    'Supply a strong-name assembly
    <Assembly: _ 
    AssemblyKeyFileAttribute("bin/ComPlusExample.snk")>
    '********************************************
    
    <TransactionAttribute(TransactionOption.Required)> _
     Public Class COMPlusServices
        Inherits ServicedComponent 
    
        Public Sub New()
            MyBase.New()
        End Sub
    
        <AutoComplete()> Public Function DoTransaction() _
         As String
            Return "Success with COM+"
        End Function
    End Class
    

    このコードは、コンポーネントを宣言するときにいくつかの型指定を排除するために、いくつかの名前空間をインポートすることから始めます。

  5. 次に、COM+ 登録の詳細を示します。 次のコード行を入力します。

    'Supply the COM+ application name 
    <Assembly: ApplicationNameAttribute("ComPlusExample")> 
    

この行は、ApplicationNameAttribute に ComPlusExample の値を割り当てます。 これは、COM+ カタログに登録されるときに COM+ アプリケーションの名前になります。 このコンポーネントが初めて呼び出されると、MMC スナップインの [COM+ アプリケーション] フォルダーに移動すると、アプリケーション名として表示されます。

コードの次の部分では、AssemblyKeyFileAttribute 属性を宣言します。

<Assembly: _ 
AssemblyKeyFileAttribute("bin/ComPlusExample.snk")>

これにより、厳密な名前に関する情報が配置されている COM+ カタログに通知されます。 を作成します。SNK ファイルは後の手順で実行しますが、COM+ にコンポーネントを記述するファイルです。

最後に、次のコードを使用して、クラス名 COMPlusServices を宣言します。

<TransactionAttribute(TransactionOption.Required)> _
 Public Public Class COMPlusServices

このクラス名の前にある 属性は、トランザクション属性を Required に設定することを COM+ に通知します。 このコード行の追加は、図 1 に示すように COM+ アプリケーション スナップインに移動し、この属性を手動で設定するのと同じです。

クラスの次のコード行は、System.EnterpriseServices 名前空間内の ServiceComponent から継承されます。

Inherits ServicedComponent 

この行を含めない場合は、COM+ でこのコンポーネントを動作させることができません。

トランザクション メソッドを追加する

このクラスのセットアップが完了したら、実際に何かを行うメソッドを作成できます。 記述したコードの DoTransaction 関数は文字列値を返しますが、このメソッドをトランザクションに参加させるために使用する必要がある構文を示しています。

<AutoComplete()> Public Function DoTransaction() As String
    Return "Success with COM+"
End Function

このメソッドの前に AutoComplete()> 属性を<付けることは重要です。 つまり、このメソッドに例外がない限り、このメソッドの終了時に SetComplete が自動的に呼び出されます。 メソッドに例外がある場合、.NET ランタイムは SetAbort メソッドを自動的に呼び出します。 これは、独自に SetComplete と SetAbort を明示的に呼び出す必要があった Visual Basic 6.0 で COM コンポーネントを記述する場合とは異なります。

厳密な名前を作成する

コンポーネントをコンパイルする前に、このコンポーネントのアセンブリに厳密な名前を付ける必要があります。 これを行わないと、COM+ カタログはコンポーネントを認識せず、登録できなくなります。 実際には、前に使用した AssemblyKeyFile 属性を使用して既にこれを行いましたが、厳密な名前ツール (Sn.exe) を使用して厳密な名前を作成し、GUID をアセンブリに関連付ける必要があります。

  1. コマンド プロンプトを開きます。

  2. 厳密な名前を作成するには、コマンド プロンプトで次のように入力し、 Enter キーを押します。

    sn -k ComPlusExample.snk
    
  3. ComPlusExample.snk ファイルをハード ドライブのルート フォルダー (おそらく C:/) から、プロジェクトがあるフォルダーの下の bin ディレクトリにコピーします。

このコンポーネントを COM+ に登録するために必要なファイルをビルドできるように、このプログラムをコンパイルする必要があります。 Visual Studio .NET の [ ビルド ] メニューの [ ビルド] をクリックします。

クライアント テスト アプリケーションを構築する

コンポーネントをビルドしたら、このコンポーネントを呼び出してテストするクライアント アプリケーションをビルドする必要があります。モジュール ファイルの Main メソッドが新しいコンポーネントのインスタンスを作成し、DoTransaction() メソッドを呼び出す単純なコンソール アプリケーションを作成します。 メインの手順を次に示します。

  1. Visual Basic .NET で、新しいコンソール アプリケーション プロジェクトを作成します。

  2. 先ほど作成したコンポーネントへの参照を追加します。

  3. 次に示すコードを入力します。

    Module modMain
        Sub Main()
            Dim objCOMPlus As New _ 
            COMPlusJumpStart.COMPlusServices()
    
            Console.WriteLine(objCOMPlus.DoTransaction)
            Console.ReadLine()
        End Sub
    End Module
    

試してみる

これで、このアプリケーションを実行して動作することを確認する準備ができました。

  1. コンポーネント サービス MMC スナップインを開き、コンポーネントが COM+ カタログに動的に登録されていることを確認します。 図 2 のようになります。

  2. コンソール アプリケーションをコンパイルして実行します。

    図 2. COM+ カタログの新しい .NET サービス コンポーネント

ロール ベース セキュリティ

多くのユーザーが COM+ で実行される COM コンポーネントを呼び出す場合は、特定のユーザーのみが特定のコンポーネントにアクセスできるように確認する必要があります。 COM+ を使用すると、ロールを定義し、それらのロールに NT ユーザーを割り当てることができます。 これらのロールが配置されたら、どのロールでどのコンポーネントを実行できるか、それらのコンポーネントのどのメソッドを実行できるかを割り当てることができます。

この同じ COMPlusServices クラスにメソッドを追加して、ロールベースのセキュリティを組み込みましょう。 Managers という名前のロールを作成し、新しいメソッドでテストして、呼び出し元が Managers ロール内にあるかどうかを確認します。

Role-Based セキュリティを追加する手順

コンポーネント サービス MMC スナップインから COM+ アプリケーションを直接変更してセキュリティ ロールを追加する代わりに、新しい属性をプロジェクトに追加します。 SecurityRoleAttribute クラスを使用して、新しい Managers ロールを追加します。 このクラスのコンストラクターには、role (string) と everyone (Boolean) の 2 つの引数があります。 role 引数は作成するロールの名前を指定し、everyone 引数は組み込みの Everyone グループをロールのユーザーに追加するかどうかを指定します。

  1. COM+ 登録の詳細というコメントのすぐ下に次のコードを入力して、COM+ アプリケーションに新しいセキュリティ ロールを追加します。

    '********************************************
    'COM+ Registration details 
    
    'Role-based security attribute
    <Assembly: SecurityRoleAttribute("Managers", False)>  
    
  2. プロセスおよびコンポーネント レベルでアクセス チェックを実行するように、セキュリティ レベルの設定を変更します。 これにより、COM+ アプリケーションにセキュリティ呼び出しコンテキストを設定できます。

  3. COM+ Services スナップインを起動します。

  4. 図 3 に示すように、[ セキュリティ ] タブをクリックし、セキュリティ レベルを変更します。

    図 3: COM+ カタログでのセキュリティ レベル プロパティの設定

手動プロセスの代わりに、アクセス レベルのチェックを実行するようにコンポーネントに属性を追加することもできます。 COMPlusServices クラスの上部にある COM+ 登録の詳細セクション内に追加するコードを次に示します。

<Assembly: ApplicationAccessControlAttribute
   (AccessChecksLevel:=AccessChecksLevelOption.ApplicationComponent)>  

セキュリティ ロールを確認する

次に、IsManager という名前のクラスに新しいメソッドを追加します。 このメソッドは、ユーザーがロール マネージャーのメンバーであるかどうかを確認するためにチェックされます。 このメソッドは関数であり、呼び出し元が Managers ロールの一部であるかどうかを示すブール値を返します。 メソッドを呼び出すユーザーのセキュリティ コンテキストにアクセスするには、SecurityCallContext クラスを使用する必要があります。 現在の呼び出し元のコンテキストを取得するには、CurrrentCall メソッドを呼び出します。 次に、IsCallerInRole メソッドを呼び出し、ロールの名前として Managers を渡します。

  1. 以下に示すメソッドを COMPlusServices クラスに追加します。

    Public Function IsManager() As Boolean
    
        Dim objCallContext As SecurityCallContext = _ 
        SecurityCallContext.CurrentCall
    
        IsManager = _ 
        objCallContext.IsCallerInRole("Managers")
    
    End Function
    

    この新しいメソッドを試すには、コンポーネントを再構築する必要があります。

  2. Visual Studio の [.NET ビルド ] メニューの [ ソリューションの再構築] をクリックします。

試してみる

  1. コンソール クライアント アプリケーションの Sub Main() メソッドのコードを変更します。 コードは次のようになります。

    Sub Main()
    
        Dim objCOMPlus As New _ 
        COMPlusJumpStart.COMPlusServices()
    
        Console.WriteLine(objCOMPlus.DoTransaction)
        Console.WriteLine(objCOMPlus.IsManager().ToString)
        Console.ReadLine()
    
    End Sub
    
  2. コンパイルした実行可能ファイルの名前を入力して、コマンド プロンプトからコンソール アプリケーションを実行します。

コードを初めて実行すると、Managers ロールにユーザーが追加されていないため、アクセスが拒否されたことを示す例外が表示されます。 これを修正するには、自分をユーザーとしてマネージャーに追加し、アプリケーションを再実行します。 今回は、例外は発生しません。 コードに例外処理を追加することもできます。 例外処理コードを使用して、クライアントが必要とするものを次に示します。

Sub Main()

Try

    Dim objCOMPlus As New _ 
    COMPlusJumpStart.COMPlusServices()

    Console.WriteLine(objCOMPlus.DoTransaction)
    Console.WriteLine(objCOMPlus.IsManager().ToString)
    Console.ReadLine()

Catch objException As Exception
    Console.WriteLine("An error occurred. " _ 
    & "Details:  " _ 
    & objException.Message)
    Console.ReadLine()

End Try

End Sub

キューに入ったコンポーネントの使用

COM+ アプリケーションでは、キューのサポートを簡単に追加できます。 アプリケーションがサーバー アプリケーションとして実行されていることを確認し (プロセス外)、[キュー] タブで Queued プロパティと Listen プロパティを設定するだけです。これらの設定が行われると、クライアント アプリケーションはコンポーネントを非同期または同期的に呼び出すことができます。 この機能の美しさは、COM オブジェクトのコードを変更する必要がないということです。COM+ カタログでそのプロパティを変更するだけです。

.NET Frameworkはキューに登録されたコンポーネントをサポートしており、予想通り、COM+ カタログを手動で変更するのではなく、属性を使用してコンポーネント キューのサポートを提供できます。

COMPlusServices クラスにメソッドを追加し、.NET クライアント アプリケーションから COM+ キューに登録されたコンポーネント サービスを使用して非同期的に呼び出してみましょう。

  1. COM+ アプリケーションをサーバー アプリケーションにします (プロセス外)。 これは、キューに登録されたコンポーネントの要件です。 属性を使用してこれを行うには、次のコードをプロジェクトに追加します。

    '********************************************
    'COM+ Registration details 
    
    <Assembly: ApplicationActivationAttribute(ActivationOption.Server)>
    
  2. コンポーネントにキューのサポートを追加します。 MSMQ キューからアクセスできるようにし、独自のキューをリッスンしてメッセージを処理できるようにします。 属性を使用してこれを行うコードを次に示します。

    '********************************************
    'COM+ Registration details 
    
    <Assembly: ApplicationQueuingAttribute(Enabled:=True, 
       QueueListenerEnabled:=True)>
    
  3. QueueTest という名前のメソッドをクラスに追加します。 サブルーチンであることを確認します。戻り値を持つことはできません。 Windows アプリケーション ログにメッセージを書き込んでもらう。 コードは次のようになります。

    Public Sub QueueTest()
        System.Diagnostics.EventLog.WriteEntry(_ 
        "COMPlusServces", "Queue Test", _ 
        Diagnostics.EventLogEntryType.Error)
    End Sub
    

これで終了です。 コンポーネントを COM+ キューに入れたコンポーネントにするためには、これで終わりです。

試してみる

次に、別のコンソール アプリケーションを作成し、このコンポーネントを呼び出すことで、このキューに入ったコンポーネントを試す必要があります。

  1. 新しいコンソール アプリケーションを作成します。

  2. このコンソール アプリケーションの Sub Main プロシージャに次のコードを追加します。

    Sub Main()
        Dim objTest As COMPlusJumpStart.COMPlusServices
        Dim strMoniker
    
        strMoniker = _ 
         "queue:/new:COMPlusJumpStart.COMPlusServices"
        objTest = GetObject(strMoniker)
        objTest.QueueTest()
    End Sub
    

これにより、コンポーネントで QueueTest メソッドが非同期的に呼び出されます。 メソッドを同期的に呼び出す場合は、コンポーネント内の他のすべてのメソッドと同じように呼び出します。

これで、このコンソール アプリケーションを実行して、このキューに登録されたコンポーネントを試すことができます。

Visual Basic 6.0 以降の COM+ の違い

.NET で同じ Visual Basic 6.0 または COM から既に知っている多くのものがあります。 しかし、これで、.NET Framework内で作業できるという利点があります。これにより、オブジェクトがスムーズに対話し、最小限のコーディングとメンテナンスを行うのに役立ちます。

この種の合理化の一般的な Visual Basic 6.0 では、SetComplete と SetAbort を独自に明示的に呼び出す必要がありました。 .NET では、SetComplete と SetAbort は AutoComplete()> 属性によって<呼び出されます。

Visual Basic .NET と Visual Basic 6.0 のもう 1 つの違いは、Visual Basic 6.0 コンポーネントはシングル スレッド アパートメント スレッド モデルを使用するため、COM+ オブジェクト プールを使用できないことです。 Visual Basic .NET コンポーネントは .NET コンポーネントであるため、Any Apartment スレッド モデルをサポートしているため、COM+ オブジェクト プールを利用できます。

まとめ

ご覧のとおり、.NET Frameworkを使用すると、COM+ が提供するサービスを簡単に利用できます。 つまり、COM と COM+ を使用して記述された既存のアプリケーションに新しい .NET コンポーネントを追加すると、それらのコンポーネントを連携させることができます。 これは非常に重要です。これは、既存の COM および COM+ コードをすべて捨てる必要がないことを意味するためです。 新しいアプリケーションを最初からビルドする場合は、はるかに効率的であるため、.NET Frameworkで完全にビルドすることを強くお勧めします。

作成者について

Tim McCarthy (MCSD、 MCT) は InterKnowlogy のプリンシパル エンジニアであり、最新の Microsoft テクノロジを利用して多層アプリケーションを設計および構築しています。 彼は DevDays の通常の講演者であり、最近、MSDN Field Content Team の .NET トレーニング コンテンツをまとめる作業を終えました。 Tim は、いくつかの Wrox Press の書籍の章を執筆しています。その中で最新の書籍は Professional VB.NET であったほか、SQL Serverマガジンの開発者 DotNET Update ニュースレターに関するいくつかの記事を執筆しています。

Paul D. Sheriff は、南カリフォルニアのカスタム ソフトウェア開発およびコンサルティング会社である PDSA, Inc.の所有者です。 Paul は南カリフォルニアの MSDN 地域ディレクターであり、Paul Sheriff Teaches Visual Basic という Visual Basic 6 の書籍の著者であり、Visual Basic、SQL Server、.NET、Keystone Learning Systems の Web 開発に関する 72 本以上のビデオを制作しています。 Paul は、 Jumpstart というタイトルの書籍 ASP.NET 共同編集しました。 詳細については、PDSA, Inc. Web サイト (www.pdsa.com) を参照してください。

情報伝達グループについて

インフォーマント・コミュニケーションズ・グループ(www.informant.com)は、情報技術分野に重点を置いた多様なメディア企業です。 ソフトウェア開発出版物、カンファレンス、カタログ発行、Webサイトを専門とするICGは、1990年に設立されました。 ICGは、米国および英国にオフィスを構え、質の高い技術情報に対する IT プロフェッショナルの高い意欲を満たす、メディアおよびマーケティング コンテンツ インテグレーターとして高い評価を受けています。

Copyright © 2002 Informant Communications Group and Microsoft Corporation

技術編集: PDSA, Inc.