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で自動生成されたクラスにインテリセンスを表示した例です。

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