連載

ASP→ASP.NET移行テクニック

第3回 ASP/ASP.NETを支える周辺技術の移行

山田 祥寛
2004/06/19
Page1 Page2 Page3 Page4

○マネージ・ラッパーの生成

 COMコンポーネントを利用する際のパフォーマンス低下の原因を改善するにはどのようにすればよいのか。

 この疑問に対して、.NET Frameworkは比較的スマートなソリューションを提供している。それがマネージ・ラッパーを介する方法だ。

 マネージ・ラッパーとは、マネージ・コード(つまり、CLRで管理されたCOMコード)アンマネージ・コード(つまり、管理されないCOMコード)の境界に立って、COMコンポーネントの呼び出しを代替するためのクラスだ。

マネージ・ラッパーを介したCOMコンポーネント呼び出し
マネージ・ラッパーとは、マネージ・コードとアンマネージ・コードの境界に立って、COMコンポーネントの呼び出しを代替するためのクラスである。

 マネージ・ラッパーを介することで、ASP.NETはあたかもCLRが管理するマネージ・コードであるかのようにCOMコンポーネントにアクセスできる。

 下記のコードを見ていただければ分かるように、変数を宣言する際にデータが明示的に宣言されているため(事前バインディング)、遅延バインディングによるパフォーマンスの劣化も解消される。

<%@ Page Language="VB" %>

<%
Dim db As ADODB.Connection = New ADODB.Connection()
db.Mode = 1
db.ConnectionString="Provider=SQLOLEDB;Password=sa;Persist Security Info=True;User ID=sa;Initial Catalog=sample;Data Source=(local)"
db.Open()
Dim rs As ADODB.RecordSet = db.Execute("SELECT title,publish,price FROM books")
%>
<html>
<head>
<title>ASP.NETによるCOMの活用</title>
</head>
<body>
<table border="1">
<tr>
  <% For i As Integer=0 To rs.Fields.Count-1 %>
    <th><%=rs.Fields.Item(i).Name %></th>
  <% Next %>
</tr>
<% Do While Not rs.EOF %>
  <tr>
  <% For i As Integer=0 To rs.Fields.Count-1 %>
    <td><%=rs.Fields.Item(i).Value %></td>
  <% Next %>
  </tr>
<%
  rs.MoveNext
Loop
rs.Close()
db.Close()
%>
</table>
</body>
</html>
マネージ・ラッパーを介してCOMコンポーネントを利用するサンプル・プログラム(adodb_net.aspx)
変数を宣言する際にデータが明示的に宣言されているため(事前バインディング)、遅延バインディングによるパフォーマンスの劣化も解消される。

 マネージ・ラッパーを生成するには、いくつかの方法があるが、ここでは.NET Frameworkに標準で付属するコマンドライン・ツールであるTlbimp.exe(タイプ・ライブラリ・インポータ)を利用してみよう。

 Tlbimp.exeは、COMコンポーネントからマネージ・ラッパーを生成するためのツールで、コマンド・プロンプトから使用することができる。例えば、ADOのマネージ・ラッパーを生成するには、以下のコマンドを実行するだけでよい。msado15.dllはADOの実体であるDLLファイルだ。

> tlbimp msado15.dll

 これを実行して、カレント・ディレクトリにADODB.dllが生成されれば成功だ。これがマネージ・ラッパーの本体であり、使用する.NETアプリケーション・ルートの「/bin」フォルダにこのDLLファイルをコピーすればよい。

 ADOのマネージ・ラッパーに含まれているラッパー・クラス群は「ADODB」名前空間に属するので、使用に当たってはあらかじめ@Importディレクティブを使用して、名前空間をインポートしておくか、クラス名をフルネームで記述する必要がある。しかし、それ以外は通常のクラス・ライブラリを使用する場合と変わりなく、既存コードにもほとんど影響を及ぼすことはないだろう。

○マネージ・コードをアンマネージ・コードから利用する

 マネージ・コードとアンマネージ・コードの相互運用を想定した場合、マネージ・コードからアンマネージ・コードの呼び出しばかりではない。アンマネージ・コードからマネージ・コードを呼び出すというケースも発生する。

 すなわち、COMコンポーネントから入れ子に呼び出していたCOMコンポーネントを部分的にマネージ・コード(.NETアセンブリ)に置き換えたというような場合である。段階的な移行や部分的な移行のようなケースを想定した場合、それは十分にあり得る話だ。

 そのような場合にも、.NET Frameworkは相互運用のための手段を提供している。それが.NET Frameworkに標準で用意されているコマンドライン・ツールであるRegasm.exe(アセンブリ登録ツール)だ。Regasm.exeは、COMクライアントがアセンブリを参照できるようにレジストリの登録を行い、また、タイプ・ライブラリを作成するための手段を提供する。

 例えば、自作の.NET用クラス・ライブラリSample.dllのレジストリ登録を行うには、以下のようにすればよい。

> regasm /tld:Sample.tlb Sample.dll

 わずかにこれだけのコマンドでSample.dllがレジストリに登録され、カレント・ディレクトリにはタイプ・ライブラリSample.tlbが生成される。これで、旧来のCOMコンポーネントを利用するのとまったく同じ手続きで、Sample.dllに含まれる.NETのクラスを呼び出すことが可能となる。

 なお、元となるアセンブリ(この場合にはSample.dll)はあらかじめグローバル・アセンブリ・キャッシュ(GAC)に登録しておく必要があるので、注意すること。アセンブリをGACに登録する方法については、後日「.NET TIPS」として公開予定なので、そちらを参照していただきたい(GACの登録について取りあえずは、MSDN:「グローバル アセンブリ キャッシュ」を参照してほしい)。

○コントロールCOMの必要性

 以上の説明で、COMと.NETとの相互運用に関する基本的なアプローチは理解いただけたことと思う。しかし、以上のアプローチはあくまでマネージ・コードとアンマネージ・コードとの境界を「越える」ことが前提となっている。繰り返しではあるが、

両者間の「境界越え」はオーバーヘッドの高い処理であり、パフォーマンス的な見地からはできるだけ避けるに越したことはない。

では、1つのコード内でいくつものCOMコンポーネントを呼び出しているようなコードはどのように移行したらよいのだろうか。そこで1つ考えられる対処方法が、複数のCOM呼び出しをつかさどる「コントロールCOM」を作成することである。

 もっとも、「コントロールCOM」なる特別なCOMの仕様があるわけではない。要は、一連のCOMコンポーネントを呼び出すための結節点となるCOMコンポーネントのことである。コントロールCOMを利用することで、マネージ・コードからアンマネージ・コードを呼び出す回数を抑えられるため、相互運用環境におけるパフォーマンスは向上する。

コントロールCOMによるオーバーヘッドの軽減
コントロールCOMを利用することで、マネージ・コードからアンマネージ・コードを呼び出す回数を抑えられるため、相互運用環境におけるパフォーマンスは向上する。

○組み込みコンポーネント

 以上、ASP .NETアプリケーションとCOMコンポーネントの相互運用について解説してきたが、ASP.NETにバージョン・アップするに当たって、標準クラス・ライブラリとして移行されたコンポーネントもある。

コンポーネント クラス/サーバ・コントロール アクセス方法
Ad Rotator asp:AdRotator コントロール <asp:AdRotator id="Ad" runat="server"
Target="_self" AdvertisementFile="ad.xml" />
<ASP:ADROTATOR ID="Ad" RUNAT="server" TARGET="_self" ADVERTISEMENTFILE="ad.xml" />
Browser Capablities Syste.Web.
HttpBrowser
Capabilities
クラス
Dim objBc As HttpBrowserCapabilities=Request.Browser
ADO ADO.NET (ActiveX Data Objects .NET) Dim db As New SqlConnection(接続文字列)
Dim com As New SqlCommand(SQLコマンド)
など
ASP.NETに移行された組み込みコンポーネント

 もしもこれらCOMコンポーネントを利用しているアプリケーションがあるならば、積極的に新しい.NETのサーバ・コントロール/クラスに移行することをお勧めしたい。

 特にデータベース連携をつかさどるADO.NETは大幅に変更されているため、移行自体が必ずしも容易な作業ではないかもしれないが、データベースへの接続はパフォーマンス上のボトルネックになりやすい個所でもあり、それだけの工数をかけるに値するのではないだろうか。ADO.NETに関する詳細は、別連載「ADO.NET基礎講座―初めての.NETデータベース・プログラミング―」が詳しい。

 以上3回にわたって、レガシーASPからASP.NETへの移行におけるポイントを概説してきた。もちろん、本稿で取り上げたものは、ごく一般的なポイントであるにすぎない。アプリケーションが複雑になればなるほど、単純には移行できない局面も多くなってくるに違いない。

 連載冒頭でも述べたが、移行の是非は、コストとパフォーマンスとのトレードオフにほかならない。移行ありきではなく、コストと工数とを考えつつ、<共存>/<統合>(垂直/水平)/<置換>などのレベルは判断されるべきであるし、その判断いかんでは、結果的に「何もしない」という判断も出てくるだろう。あるいは、レガシーな資産を完全に破棄し、ASP.NETで1から開発を行うという選択肢も(場合によっては)あるかもしれない。最終的にその是非を判断するのは、あくまで現場でアプリケーションを目の前にした読者諸兄である。

 本稿が、読者諸君にとっての1つの指標となることを願う。End of Article

 

 INDEX
  ASP→ASP.NET移行テクニック
  第3回 ASP/ASP.NETを支える周辺技術の移行
    1.言語上の相違点
    2.「高速モード」のJScript .NETにおける制限事項
    3.COMコンポーネントの活用(1)
  4.COMコンポーネントの活用(2)
 
インデックス・ページヘ  「ASP→ASP.NET移行テクニック」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間