ASP.NE Web Siteプロジェクト(ASP.NET Web Applicationプロジェクトではありません)を作成すると、App_Codeに拡張子がxsd,wsdlなどのファイルを配置すると、自動的にプロキシが作成されます。これはWeb.configのsystem.webタグの直下にあるcompilationタブのbuildProvidersタグに拡張子に対応するBuildProviderが設定されているため、ビルドプロバイダがプロキシを作成することで実現されます。BuildProviderを作成するにはCodeDomの知識が必要です。
今回は同じようにカスタムビルドプロバイダを作成してみます。
動作確認環境
- ASP.NETサーバー : Visual Studio 2008 Professional(英語版)組み込みサーバ
- クライアント: IE 7.0
- 開発環境: Visual Studio 2008 Professional 英語版
- .NET 3.5(.NET 2.0以上ならOKのはず)
作成するプロジェクトの種類について
今回作成するのは"Web サイト"プロジェクトです。Webアプリケーションプロジェクトではないので注意して下さい。 ASP.NET Web Applicationプロジェクトでは、今回作成するBuildProviderはうまく動作しません。リンク先MSDNライブラリの中段のメモを参照して下さい。
- BuildProvider クラス
http://msdn.microsoft.com/ja-jp/library/system.web.compilation.buildprovider.aspx
1. カスタムBuildProviderが対象とするファイルのスキーマ定義
以下のxmlファイルを対象とします。ファイル名はStand.jojoとします。(ファイル名やスキーマはとくに深い意味はありませんので)
<?xml version="1.0" encoding="utf-8" ?>
<stands>
<stand name="DeepPurple">
<growth>S</growth>
<power>3</power>
<speed>4</speed>
</stand>
</stands>
2. ソリューションの作成
Visual Studio 2008を起動して、空のソリューションを新規作成します。ソリューション名はBuildProviderとしました。
2.1 カスタムBuildProviderの作成
ソリューションエクスプローラから、ソリューションを右クリック→Add→New ProjectからClass Libraryプロジェクトを作成します。プロジェクト名はStandBuildProviderとしました。
既定で作成されるClass1.csをStand.csにリネームし、以下のように編集します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Compilation;
using System.Xml;
using System.CodeDom;
using System.IO;
namespace StandBuildProvider
{
public class StandBuildProvider : BuildProvider
{
public override void GenerateCode(AssemblyBuilder assemblyBuilder)
{
XmlDocument xml = new XmlDocument();
using (Stream s = OpenStream())
{
xml.Load(s);
}
XmlNode stand = xml.SelectSingleNode("/stands/stand");
string standName = stand.Attributes["name"].Value;
XmlNode growthPotential = stand.SelectSingleNode("growth");
string growthPotentialValue = growthPotential.InnerText;
XmlNode power = stand.SelectSingleNode("power");
string powerValue = power.InnerText;
XmlNode speed = stand.SelectSingleNode("speed");
string speedValue = speed.InnerText;
CodeCompileUnit ccu = new CodeCompileUnit();
CodeNamespace cn = new CodeNamespace();
cn.Name = "StandProxy";
cn.Imports.Add(new CodeNamespaceImport("System"));
CodeMemberProperty nameProp = new CodeMemberProperty();
nameProp.Name = "StandName";
nameProp.Type = new CodeTypeReference(typeof(string));
nameProp.Attributes = MemberAttributes.Public;
nameProp.GetStatements.Add(new CodeSnippetExpression("return \"" + standName + "\""));
CodeMemberProperty growthProp = new CodeMemberProperty();
growthProp.Name = "Growth";
growthProp.Type = new CodeTypeReference(typeof(string));
growthProp.Attributes = MemberAttributes.Public;
growthProp.GetStatements.Add(new CodeSnippetExpression("return \"" + growthPotentialValue + "\""));
CodeMemberProperty powerProp = new CodeMemberProperty();
powerProp.Name = "Power";
powerProp.Type = new CodeTypeReference(typeof(int));
powerProp.Attributes = MemberAttributes.Public;
powerProp.GetStatements.Add(new CodeSnippetExpression("return " + powerValue));
CodeMemberProperty speedProp = new CodeMemberProperty();
speedProp.Name = "Speed";
speedProp.Type = new CodeTypeReference(typeof(int));
speedProp.Attributes = MemberAttributes.Public;
speedProp.GetStatements.Add(new CodeSnippetExpression("return " + speedValue));
CodeTypeDeclaration ctd = new CodeTypeDeclaration(standName);
ctd.Members.AddRange(new CodeTypeMember[] { nameProp, growthProp, powerProp, speedProp });
cn.Types.Add(ctd);
ccu.Namespaces.Add(cn);
assemblyBuilder.AddCodeCompileUnit(this, ccu);
}
}
}
上記のプログラムにより、standタグの属性nameと名前が同じクラスが作成されます。作成されるプロキシクラスで、growth,speed,powerタグはプロパティとして現されます。
2.2 サンプルサイトの作成
ソリューションエクスプローラを右クリックし、Add→New Web Siteを選択し、WebSiteというWebサイトプロジェクト作成します。サイトプロジェクトを右クリック→Add Referenceを選択し、StandBuildProviderプロジェクトへの参照をプロジェクトに追加します。次のWeb.configを編集して、ビルドプロバイダと拡張子を関連付けます。
<system.web>
<!-- 省略 -->
<compilation debug="true">
<buildProviders>
<add extension=".jojo" type="StandBuildProvider.StandBuildProvider, StandBuildProvider"/>
</buildProviders>
</compilation>
</system.web>
次に1. カスタムBuildProviderが対象とするファイルのスキーマ定義で定義したxmlをStand.jojoという名前で、App_Codeフォルダに作成します。
すぐに、クラスが自動作成されます。クラス作成後はインテリセンスも働きます。以下の図は既定で作成されるDefault.aspx.csで自動生成されたクラスにインテリセンスを表示した例です。

説明は以上です。誤り、指摘とうがあればご連絡ください。