VS2008 複数フレームワーク対応の中身(Windowsアプリ、コンソールアプリ編)
VS2008では.NET Framework 2.0/3.0/3.5 のフレームワークに対応したアプリケーションを構築することが可能になりました。
この対応の中身なんですが、VS2008が行っているのは各フレームワークにあわせて読み込むdllの設定を変更しているだけで、コンパイラはC#であればC# 3.0用のコンパイラを使ってすべて処理しているようだ、という話をVSUGのコラムに以前まとめました。
このときはコンパイラのバージョンを確認しておらず、動作の具合から推測していただけだったんですが、今日その部分を確認する方法をのせている記事を見つけました。
ピンポイントで速習!Visual Studio 2008 Part2 Visual Studio 2008移行での注意点(2ページ)
プロジェクトのリビルドを実行すると、出力ウィンドウに利用しているコンパイラが表示されます。
ここでFrameworkのターゲットを2.0にしている場合でもC# 3.0のコンパイラが動作していることを確認しました。
推測の裏づけがとれて、気分すっきり(w
VS2008 複数フレームワーク対応の中身(ASP.NET編)
ASP.NETでは複数フレームワーク対応はどのように行われているのでしょうか。
これは、ターゲットフレームワークを変更したときにweb.configがどのように変わるかを見ればすぐわかります。
2.0がターゲットの場合、web.configにはほとんど記述がありませんが、3.5に変更するといろいろな記述が増えます。
その中でも重要なのはsystem.web-compilation-assembliesに3.5で利用されるdllが追加されること、また、system.codedom-compilers-compilerで利用されるコンパイラのバージョンが3.5用に設定されることの2点です。
さて、このweb.configでの設定ですが、どこまで影響を与えているのか確かめてみましょう。
ターゲットを3.5にしたときには特に影響は見えないので、ターゲットを2.0としてWebサイトプロジェクト、Webアプリケーションプロジェクトを構築します。
○インラインコードにvarを記述
まずWebサイトでインラインでvarを利用したプログラムを記述したaspxファイルを用意します。
<%@ Page language="c#" %>
<script runat="server">
void Page_Load(Object sender, EventArgs e)
{
var tmp = "テスト";
Message.Text = tmp;
}
</script>
<html>
<body>
<form id="Form1" runat="server">
<asp:label id="Message" runat="server"/><br />
</form>
</body>
</html>
こんなファイルを作成し、実行すると、’var’が見つからない、というコンパイルエラーが発生します。
次にWebアプリケーションで同じaspxファイルを実行してみます。
Webアプリケーションでwebフォームページを追加すると勝手にコードビハインドのファイルが追加されてしまいますが、そのコードファイルは削除し、aspxファイルを上記のとおり書き換えて実行してみればよいでしょう。
この場合も’var’が見つからない、というコンパイルエラーが発生します。
○コードビハインドファイルにvarを記述
次にWebサイトのaspxファイルにラベルを追加し、コードビハインドファイルのPage_Loadからそこに値を設定するようなプログラムを記述してみましょう。
protected void Page_Load(object sender, EventArgs e)
{
var tmp = "テスト";
Label1.Text = tmp;
}
こんな感じでプログラムを記述し、実行すると、やっぱり’var’が見つからない、というコンパイルエラーが発生します。
さて、Webアプリケーションで同じようにコードビハインドファイルに記述し、実行してみるとどうでしょうか?
このとき、エラーは発生せず、きちんとページが表示され、そこに"テスト"という文字列が表示されます。
この動作ですが、WebアプリケーションプロジェクトとWebサイトプロジェクトの違いがしっかり頭にはいっていれば不思議なことはないはずです。
Windowsアプリ、コンソールアプリ編で記述したように、VS2008ではコンパイラはC# 3.0のコンパイラを利用します。
Webアプリケーションプロジェクトで最初にすべてのコードをコンパイルするときは、VS2008が行う作業なので、このタイミングではC# 3.0のコンパイラが利用されるのです。このため、varはエラーになりません。
Webアプリケーションプロジェクトでも、aspxファイルからソースが生成され、コンパイルが行われるときはweb.configに記述されたコンパイラが利用されるため、ターゲットフレームワークが2.0で特にweb.configにコンパイラの記述がない場合はC# 2.0のコンパイラを利用し、varはエラーとなります。
Webサイトプロジェクトではすべてのコードは実行時にコンパイルされるため、web.configの設定に従いC# 2.0のコンパイラが利用されるために、インラインでもコードビハインドでもvarはエラーになります。
ちょっとややこしいかなぁ?
どのタイミングで、何が、なぜ動くのか、という観点で整理して考えていくと理解できるんじゃないかと思います。
WebアプリケーションプロジェクトとWebサイトプロジェクト
ASP.NETでプロジェクトを作成する場合、WebアプリケーションプロジェクトとWebサイトプロジェクトの2種類のプロジェクトを作成することができます。
この2種類のプロジェクトの違いについて説明してみたいと思います。
○歴史的経緯
VisualStudio.NET(.NET Framework 1.0)およびVisualStudio.NET 2003(.NET Framework 1.1) においては、Webアプリケーションプロジェクトしかありませんでした。
これがVisualStudio 2005(.NET Framework 2.0)になると、当初はWebサイトプロジェクトしか作成できなくなりました。
Webサイトプロジェクトは、プロジェクトの作成時点ではweb.configさえ作らないというように、ASP.NETの実行に最低限必要なものだけをプロジェクトの内部に作成するようになっており、私はこの変化を喜ばしいものと思っていました。
ただ、この変更(Webアプリケーション→Webサイト)で問題が発生する人たちもいました。
それは、Ver 2.0以前にASP.NETでWebアプリケーションを構築し、そこでユーザコントロール等を利用していた人たちで、そのWebアプリケーションをアップグレードして実行しようとするとうまくユーザコントロールが使えない、といった状況が発生していたのです。
このような問題を解消するためもあり、VisualStudio 2005 SP1でWebアプリケーションプロジェクトが追加されました。
VisualStudio 2008ではスタートページからはWebアプリケーションプロジェクトしか作れませんが、メニューからたどることでWebサイトプロジェクトも作成できるようになっています。
○WebアプリケーションプロジェクトとWebサイトプロジェクトの違い
この2種類のプロジェクトの何が違うのかみてみましょう。
Webアプリケーションプロジェクトでは、コードビハインドファイル、クラスファイル等のすべてのコードファイルをあらかじめコンパイルし、dllファイルを作成してbinフォルダに配置する必要があります。
Webサイトプロジェクトではすべてのコードファイルは実行時にaspxファイルとともにコンパイルされます。また、クラスファイルはApp_Codeフォルダに配置しなければいけません。
VSでデバッグ実行をしたときの流れで2種類のプロジェクトを比較すると、次の図のような違いがあります。
デバッグ実行を開始すると、まずビルドが行われますが、ここでWebアプリケーションプロジェクトはコードファイルをコンパイルし、binフォルダにdllを配置します。
Webサイトプロジェクトでもビルドが行われますが、ここではコンパイルエラーのチェックが行われているだけです。
次にブラウザが起動され、スタートアップに設定されているページ等が表示されるわけですが、このタイミングでWebアプリケーションプロジェクトではaspxファイルから自動的にソースコードが生成され、それがコンパイルされてプロジェクトの実行が開始されます。
Webサイトプロジェクトでは、aspxファイルからのソースコード自動生成が行われるとともに、ここであらためてすべてのコードがコンパイルされ、プロジェクトの実行が開始されます。
○違いが与える影響
2種類のプロジェクトが異なることで、どのような影響があるのが具体例を2つ述べてみます。
最初の例はLINQ to SQLクラスを追加した後の動作です。
Webアプリケーションプロジェクトでは、追加したLINQ to SQL クラスはルートの直下に作成されます。
また、LinkDataSourceコントロールを追加した場合、そのコントロールで利用するLINQ to SQL クラスをウィザードで設定することができますが、一度ビルドを実行したあとでないと、このウィザードから作成した直後のLINQ to SQLクラスを指定することができません。
Webサイトプロジェクトでは、追加したLINQ to SQL クラスはApp_Codeフォルダに作成されます。また、特にビルドを実行しなくてもLinkDataSourceコントロールのウィザードから指定することができます。
もう一つの例は階層型マスターページを利用する場合です。
Webサイトプロジェクトではマスターページや通常のWebページを追加する時点で、その上位にかぶせるマスターページを設定するかどうかチェックを入れることができ、そこで指定をするだけで階層型のマスターページを利用することができます。
これに対して、Webアプリケーションプロジェクトではトップのマスターページ、階層下マスターページ(Nested Master Page)、コンテンツページ(Web Content From)をそれぞれ指定する必要があり、通常のWebフォームとは別のテンプレートを利用しなければいけません。
このような影響は、コンパイルのタイミングだけでなく、WebアプリケーションプロジェクトとWebサイトプロジェクトでプログラム内から外部のクラスを呼び出す方法が異なることからも発生します。
○どちらのプロジェクトを利用するか?
プロジェクトを一から構築する場合であれば、WebアプリケーションプロジェクトとWebサイトプロジェクトのどちらを利用しても特に大きな違いはありません。
以前に作成したプロジェクトをアップデートしたい、とか、すでに作成ずみのクラスやユーザコントロールを利用したい、といったときにどちらのプロジェクトであれば構築しやすいかを気にすればよいと思います。