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

Microsoft .NET へのアップグレード

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

February 2002
日本語版最終更新日 2002 年 9 月 19 日

要約 : 新しい Microsoft .NET コンポーネントを既存の COM および COM+ アプリケーションに追加し、アプリケーション内でそれらのコンポーネントが共に機能できるようにします。この技術は、トランザクションに参加する、ロール ベースのセキュリティを利用する、またはキューと対話する、などの機能を持つ .NET アプリケーションの開発する際に役立ちます。

目的

  • Microsoft® .NET での COM+ サービスの使用法を学習する
  • サービス コンポーネントを作成する
  • サービス コンポーネントを配置する

想定される読者

この記事を読むにあたっては、次の項目についての経験が必要になります。

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

目次

.NET で COM+ サービスを使用する
トランザクション ベースのコンポーネントを開発する
ロール ベースのセキュリティ
キュー コンポーネントを使用する
Visual Basic 6.0 と比較した COM+ の相違点
まとめ

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

多くのユーザーは、Visual Basic または C++ で作成したコンポーネントをホストするためにおそらく COM+ アプリケーションを使用したことがあるでしょう。COM+ は、トランザクション、キュー コンポーネント、ジャスト イン タイム アクティベーション、ロール ベースのセキュリティ、共有プロパティなどの、有益なサービスを数多く提供しています。COM+ を利用してコンポーネントをホストする利点の 1 つは、コンポーネントの [トランザクション サポート] を [必要] と設定するなどのコンポーネントの動作変更を、コードを作成することなく実行できることです。コンポーネント サービス MMC スナップインから COM+ コンポーネントにラジオ ボタンを設定することにより、コンポーネントは、作成するたびに COM+ トランザクションのコンテキスト内で作成されます。コンポーネントが COM+ トランザクションを使用すると、すべてのデータベース トランザクションは分散トランザクション コーディネータ (DTC) によって処理されます。図 1 は、コンポーネント サービスのインターフェイスで [トランザクション サポート] を [必要] と設定する例を示しています。

ms973809.comservnet01(ja-jp,MSDN.10).gif

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


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

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

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

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


COM+ サービス説明
自動トランザクション処理宣言型のトランザクション処理機能を適用します。
COM Transaction Integrator (COMTI)CICS および IMS アプリケーションを Automation オブジェクトにカプセル化します。
コンペンセート リソース マネージャ (CRM)非トランザクション リソースに atomicity および durability プロパティを適用します。
ジャスト イン タイム アクティベーションメソッド呼び出しの際にオブジェクトをアクティブ化し、呼び出しが返された時点でオブジェクトを非アクティブ化します。
疎結合イベント (LCE)オブジェクト ベースのイベントを管理します。
オブジェクト構築クラス インスタンスの作成時に、そのインスタンスに永続的な文字列値を渡します。
オブジェクト プーリング作成済みオブジェクトのプーリングを提供します。
キュー コンポーネント非同期のメッセージ キューを提供します。
ロール ベースのセキュリティロールに基づいてセキュリティ許可を適用します。
共有プロパティサーバー プロセス内の複数のオブジェクトで状態を共有します。
同期 (アクティビティ)同時実行を管理します。
XA 相互運用性X/Open トランザクション処理モデルをサポートします。

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

トランザクションに参加する、ロール ベースのセキュリティを利用する、キューと対話する、などの機能が必要な .NET アプリケーションを作成する場合は、.NET に用意されている COM+ サービスを利用することができます。後で説明するとおり、.NET ではこれらのサービスを簡単に実装することができます。

ヒント : .NET コードを COM+ サービスと連動する必要がない場合、つまり、.NET Framework だけですべての処理を行う場合は、System.EnterpriseServices クラスを使用しないでください。このクラスを使用すると、パフォーマンスが低下することがあります。

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

COM+ サービスと対話するコンポーネントを .NET で作成する場合は、以下の手順を実行します。表 2 では、各手順の用語について説明します。

  1. クラス ライブラリを作成します。
  2. System.EnterpriseServices.ServicedComponents クラスから派生するようにすべてのクラスを作成します。
  3. アセンブリを作成します。
  4. 厳密な名前を作成します。

    表 2. .NET コンポーネントの作成に関連する用語の定義


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

トランザクション ベースのコンポーネントを開発する

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

COM+ トランザクション コンポーネントを作成する

.NET コンポーネントを COM+ サービスで実行できるようにするには、いくつかの手順があります。まず、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+ 登録の詳細
    
    ' COM+ アプリケーション名を指定します。
    <Assembly: ApplicationNameAttribute("ComPlusExample")> 
    
    ' 厳密な名前のアセンブリを指定します。
    <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 "COM+ 成功"
        End Function
    End Class
    
    

    このコードの最初の部分では、コンポーネントを宣言する際に入力を省略できるようにいくつかの名前空間をインポートしています。

  5. コードの次の部分は COM+ 登録の詳細です。次のコードを入力します。
    
    
    ' COM+ アプリケーション名を指定します。
    <Assembly: ApplicationNameAttribute("ComPlusExample")> 
    
    


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

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



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

この属性は、厳密な名前に関する情報が置かれる場所を COM+ カタログに指定します。後の手順で .SNK ファイルを作成しますが、COM+ に対するコンポーネントを記述するファイルはこのファイルです。

最後にクラス名 COMPlusServices を次のように宣言します。



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

クラス名の前の属性は、トランザクション属性を [必要] と設定することを COM+ に知らせるためのものです。このコードを追加することは、COM+ アプリケーション スナップイン (図 1) に移動して、この属性を手動で設定することと同じ効果があります。

クラスの次のコード行は、System.EnterpriseServices 名前空間の ServicedComponent から派生しています。



Inherits ServicedComponent
                

この行を入力しないと、このコンポーネントを COM+ で実行できません。

Transaction メソッドを追加する

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



<AutoComplete()> Public Function DoTransaction() As String
    Return "COM+ 成功"
End Function
                

メソッドの先頭に <AutoComplete()> 属性を設定することは重要です。この設定により、メソッドで例外が生じなかった場合はメソッドの終了時に SetComplete が自動的に呼び出されます。例外が生じた場合は、.NET ランタイムにより SetAbort メソッドが自動的に呼び出されます。この方法は Visual Basic 6.0 で COM コンポーネントを作成するときの方法とは異なります。Visual Basic 6.0 では、SetComplete および SetAbort を自分で明示的に呼び出る必要がありました。

厳密な名前を作成する

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

  1. コマンド プロンプトを開きます。
  2. 厳密な名前を作成するには、コマンド プロンプトに次のコマンドを入力して Enter キーを押します。
    
    
    sn -k ComPlusExample.snk
    
    

  3. ハード ディスクのルート ディレクトリ (通常は C:\) にある ComPlusExamples.snk ファイルを、プロジェクトが置かれているフォルダ内の 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. コンソール アプリケーションをコンパイルおよび実行します。

    ms973809.comservnet02(ja-jp,MSDN.10).gif

    図 2. COM+ カタログに新しく追加された .NET サービス コンポーネント


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

COM+ で実行する COM コンポーネントを呼び出すユーザーが複数いる場合は、特定のユーザーだけが特定のコンポーネントにアクセスできる状態にする必要があります。COM+ では、ロールを定義し、それらのロールに NT ユーザーを割り当てることができます。ロールを定義した後は、各ロール対して、どのコンポーネントの実行を許可するか、およびコンポーネントのどのメソッドの実行を許可するかを割り当てることができます。

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

ロール ベースのセキュリティを追加するための手順

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

  1. COM+ 登録の詳細というコメントの下にあるコードを入力して COM+ アプリケーションに新しいセキュリティ ロールを追加します。
    
    
    '********************************************
    ' COM+ 登録の詳細
    
    ' ロールベースのセキュリティ属性
    <Assembly: SecurityRoleAttribute("Managers", False)>  
    
    

  2. セキュリティ レベルの設定を変更し、プロセス レベルおよびコンポーネント レベルでアクセス チェックを実行します。この変更により、COM+ アプリケーションでセキュリティ呼び出しコンテキストが有効になります。
  3. COM+ サービス スナップインを起動します。
  4. [セキュリティ] タブをクリックし、図 3 のようにセキュリティ レベルを変更します。

    ms973809.comservnet03(ja-jp,MSDN.10).gif

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


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



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

セキュリティ ロールをチェックする

ここでは、IsManager という名前のクラスに新しいメソッドを追加します。このメソッドは、ユーザーが Managers のロールのメンバであるかどうかをチェックするためのものです。このメソッドは関数で、呼び出し元が Managers ロールのメンバであるかどうかを示すブール値を返します。メソッドを呼び出しているユーザーのセキュリティ コンテキストへのアクセスを取得するには、SecurityCallContext クラスを使用する必要があります。現在の呼び出し元ユーザーのコンテキストを取得するには、CurrentCall メソッドを呼び出します。次に、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 ロールにユーザーが追加されていないため、アクセスが拒否されたことを表す例外が生じます。これを解決するには、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("エラーが発生しました。 " _ 
    & "詳細 :  " _ 
    & objException.Message)
    Console.ReadLine()

End Try

End Sub
                

キュー コンポーネントを使用する

COM+ アプリケーションでは、キュー サポートを簡単に追加できます。アプリケーションがサーバー アプリケーション (アウト プロセス) として実行 していることを確認し、[キュー] タブで Queued プロパティおよび Listen プロパティを設定するだけです。この設定により、クライアント アプリケーションは作成したコンポーネントを同期または非同期に呼び出すことができます。この方法の利点は、COM+ カタログで COM オブジェクトのプロパティを変更すれば、COM オブジェクトのコードを変更する必要がない点です。

.NET Framework は、キュー コンポーネントをサポートしています。そのため、COM+ カタログを手動で変更するのではなく、属性を使用することにより、コンポーネントにキュー サポートを追加することができます。

ここでは、COMPlusServices クラスに 1 つのメソッドを追加し、COM+ キュー コンポーネント サービスを使用して .NET クライアント アプリケーションからこのメソッドを非同期で呼び出します。

  1. COM+ アプリケーションをサーバー アプリケーション (アウト プロセス) として実行します。これはキュー コンポーネントの 1 つの条件です。これを属性を使用して行う場合は、プロジェクトに次のコードを追加します。
    
    
    '********************************************
    ' COM+ 登録の詳細
    
    <Assembly: ApplicationActivationAttribute(ActivationOption.Server)>
    
    

  2. コンポーネントにキュー サポートを追加します。コンポーネントが MSMQ キューにアクセスできるようにし、メッセージを処理するためにコンポーネント専用のキューをリッスンできるようにします。属性を使用してこれを行う場合のコードは次のとおりです。
    
    
    '********************************************
    ' COM+ 登録の詳細
    
    <Assembly: ApplicationQueuingAttribute(Enabled:=True, 
       QueueListenerEnabled:=True)>
    
    

  3. QueueTest というクラスにメソッドを追加します。このメソッドがサブルーチンであることを確認してください。このメソッドが戻り値を持つことはできません。Windows アプリケーション ログにメッセージを書き込むように設定します。コードは次のようになります。
    
    
    Public Sub QueueTest()
        System.Diagnostics.EventLog.WriteEntry(_ 
        "COMPlusServces", "キュー テスト", _ 
        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+ の相違点

Visual Basic 6.0 および COM のさまざまな特徴は .NET にも引き継がれています。ただし、.NET Framework では、オブジェクト間の円滑な対話が促進されており、開発者のコーディングとメンテナンスも最低限ですむため、.NET Framework 内で処理を行うことには多くの利点があります。

この典型的な相違に、Visual Basic 6.0 では SetComplete および SetAbort を明示的に呼び出す必要がありましたが、.NET では SetComplete および SetAbort は <AutoComplete()> 属性で呼び出される、というものがあります。

また、Visual Basic .NET と Visual Basic 6.0 の別の違いでは、Visual Basic 6.0 のコンポーネントは STA (Single Threaded Apartment) スレッド モデルを使用するため、COM+ オブジェクト プーリングを利用できません。Visual Basic .NET コンポーネントは .NET コンポーネントであり、Any Apartment スレッド モデルをサポートしているため、COM+ オブジェクト プーリングを利用することができます。

まとめ

このように .NET Framework では、COM+ のさまざまなサービスを簡単に利用することができます。これは、COM または COM+ で作成された既存のアプリケーションに新しい .NET コンポーネントを追加し、それらを同時に実行することができる、ということです。これまで開発した COM コードおよび COM+ コードを無駄にすることがないため、この特徴は非常に重要です。新しいアプリケーションを最初から作成する場合は、高機能を備えた .NET Framework ですべての作成を行うことをお勧めします。

著者について

Tim McCarthy (MCSD、MCT) は、最新の Microsoft テクノロジを駆使して、複数の層を持つアプリケーションの設計とビルドを行っている InterKnowlogy 社の主任エンジニアです。DevDays での常任講師も勤めており、最近、MSDN®フィールド コンテンツ チーム用の .NET トレーニング コンテンツを完成させました。同氏は Wrox Press 社の書籍の執筆も行っており、最近の著作としては『Professional VB.NET』、および『SQL Server Magazine』の Developer DotNET Update ニュースレターなどがあります。

Paul D. Sheriff は、PDSA, Inc (www.pdsa.com) のオーナーです。この会社は、南カリフォルニアで特注ソフトウェアの開発とコンサルタント業を行っています。Paul は、MSDN Regional Director for Southern California で、Visual Basic 6 関連の『Paul Sheriff Teaches Visual Basic』の著者です。また、Keystone Learning Systems の Visual Basic、SQL Server、.NET、Web 開発のビデオを 72 本以上製作しています。Ken Getz と共同で執筆した SAMS の『ASP.NET Jumpstart』が近日刊行予定です。詳細については、PDSA, Inc. の Web ページ (www.pdsa.com) を参照してください。

Informant Communications Group について

Informant Communications Group, Inc (www.informant.com) は、多角的なメディア企業であり、情報技術部門に特に力を注いでいます。1990 年に創設され、ソフトウェア開発に関する書籍の発行、会議の主催、カタログの発行、および Web サイトの運営を行っています。米国と英国に事務所を構え、メディアおよびマーケティングのコンテンツ インテグレータとして高い評価を受けており、質の高い技術情報を必要とする IT スペシャリストに有用な情報を提供しています。

Copyright c 2002 Informant Communications Group and Microsoft Corporation

監修 : PDSA, Inc.


表示: