連載

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

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

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

COMコンポーネントの活用

 レガシーASPでアプリケーションを構築している場合、多くの開発者がCOMコンポーネントを利用しているはずだ。COMは優れたコンポーネント技術であり、複雑なビジネス・オブジェクトを抽象化する場合には欠かせない存在であった。恐らくレガシーASPからASP.NETへ移行する場合にも、現存のアプリケーションが依存するCOMコンポーネントを完全に捨て去ることは大変難しいのではないだろうか。

 しかし、心配することなかれ。ASP.NET(というよりも.NET Framework)では既存のCOMコンポーネントを引き続き活用するためのいくつかの手段を提供している。

○Server.CreateObjectメソッド

 結論からいおう。

ASP.NETでは、旧来のServer.CreateObjectメソッドを使用することで、従来のCOMコンポーネントのほとんどを「そのまま」利用することができる。
 利用するに際して注意すべき点は2点だ。

(1)ASP.NETはMTAベースのCOMしか利用できない

 COMコンポーネントのアパートメント・モデルは、STA(Single Thread Apartment-model)とMTA(Multi Thread Apartment-model)とに大別される。アパートメントとは、COMコンポーネントを実行するための単位で、COMクライアントごとに生成される。

 STAとMTAの主な違いは、1つのアパートメントに含まれるCOMコンポーネントを同時に実行できるかどうかという点で、MTAは同時実行できるが、STAはできない。

アパートメントの概念
STAとMTAとの主な違いは、1つのアパートメントに含まれるCOMコンポーネントを同時に実行できるかどうかという点で、MTAは同時実行できるが、STAはできない。

 STAの場合には、アパートメントが要求キューを管理する仕組みを備えており、COMクライアントからのCOMコンポーネント呼び出しに際しては、必ずキューを経由しなければならない。これによって、アパートメント内では1つのCOMコンポーネントしか実行されないことが保証されるというわけだ。

 一方のMTAでは、こうしたキューの仕組みは用意されていないので、アパートメント内部のCOMコンポーネントが同時に複数のスレッドから呼び出される可能性がある。そのため、COMコンポーネントは、複数のスレッドからの同時要求を受けても問題なく動作するような仕組みを備えていること、つまり「スレッド・セーフ」であることが求められる。

 ASP.NETでは、この大きく2種類に分類されるCOMコンポーネントのうち、「デフォルトで」MTAのコンポーネントしか動作できない。ASP.NETでSTAのコンポーネントを利用する場合には、明示的に以下のような宣言を行う必要があるのだ。

<%@ Page AspCompat="True" %>
ASP.NET環境でSTAのコンポーネントを利用するための宣言
ASP.NET環境でSTAのコンポーネントを利用するためには、@PageディレクティブのAspCompat属性にTrueを設定する。

 例えば、ASP.NET環境で旧来のADO(ActiveX Database Objects)コンポーネントを利用する場合にも、以下のようにすればよいだけだ。

<%@ Page Language="VB" AspCompat="True" %>
<%
Dim db = Server.CreateObject("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 = 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>
ASP.NET環境で旧来のADOコンポーネントを利用するサンプル・プログラム(ado.aspx)

 この方法は、多くのレガシーASPアプリケーションを「ほとんどそのまま」ASP.NETに移行したいという場合に有効な手法だ。しかし、半面で問題点もある。というのも、AspCompat属性にTrueを設定した場合、Webフォーム・ページ自体がSTAで動作してしまうのだ。これは、せっかくのASP.NETの高速性を減殺してしまう結果にもつながりかねない。

(2)生成されたオブジェクトは遅延バインディングされる

 また、Server.CreateObjectメソッドを使用して生成されたオブジェクトは遅延バインディングされる。つまり、コンパイル時ではなく、実行時にデータ型が決定されるため、ここでもパフォーマンス上のネックとなってしまうのだ。

 ここで紹介した手法は、あくまで移行に手間をかけたくないという場合に(あるいは、上記のようなオーバーヘッドがそれほどネックにならない程度のアプリケーションでのみ)使用するべきだ。

 それでは、上記のようなパフォーマンス低下の原因を改善するにはどのようにすればよいのか。次にその方法について解説しよう。


 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 記事ランキング

本日 月間