Egen Build Provider / Visual Studio 2005
HejFra en bog (WROX: Professional ASP.NET 2.0, http://www.wrox.com/WileyCDA/WroxTitle/Professional-ASP-NET-2-0-Special-Edition.productCd-0470041781.html) forsøger jeg at køre et eksempel, men jeg gør det åbenbart forkert, så jeg håber på eksperthjælp ;)
Det drejer sig om at bygge sin egen Build Provider, således at en klasse der parser et xml-dokument kan tilgåes overalt i koden i stil med dette:
EvjenCar newCar = new EvjenCar();
Response.Write(newCar.Color + "<br />");
Response.Write(newCar.Doors.ToString() + "<br />");
Et eksempel på et xml-dokument med kunne være
.Car - fil
<?xml version="1.0" encoding="utf-8" ?>
<car name="EvjenCar">
<color>Blue</color>
<door>4</door>
<speed>150</speed>
</car>
Sådan er strukturen: En .car-fil indlæses og værdierne af xml-noderne kan nemt tilgåes i koden ved EvjenCar newCar = new EvjenCar();
Nu vil jeg forsøge at forklare fra a til z hvad jeg gør, så I måske kan fortælle mig hvad jeg gør galt:
(visual Studio 2005 C#)
1) oprette en ny WebApplication
2) Tilføje (add) endnu et projekt, men denne gang et "Class Library". Dette kaldes CarBuilderProvider.
Nu har jeg to projekter.
CarBuilderProvider-projektet indeholder kun en class, som hedder car.cs. Denne klasse parser xml'en. Jeg mener koden er uden betydning, men har pastet den nederst i denne tråd.
3) nu laver jeg en App_Code folder, i webappl-projektet og proper min test.car (xml) fil ind i
4) min web.config-fil tilføjes følgende:
<configuration>
<system.web>
<compilation debug="false">
<buildProviders>
<add extension=".car" type="CarBuildProvider.Car"/>
</buildProviders>
</compilation>
</system.web>
</configuration>
5) nu skulle jeg kunne tilgå min Car, ved i koden at skrive:
protected void Page_Load(object sender, EventArgs e)
{
EvjenCar newCar = new EvjenCar();
}
meen det virker IKKE EvjenCar kan ikke findes.
Hvad gør jeg galt?
CarBuildProvider.cs
--------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Web.Compilation;
using System.Xml;
using System.CodeDom;
namespace CarBuildProvider
{
class Car : BuildProvider
{
public override void GenerateCode(AssemblyBuilder myAb)
{
XmlDocument carXmlDoc = new XmlDocument();
using (Stream passedFile = this.OpenStream())
{
carXmlDoc.Load(passedFile);
}
XmlNode mainNode = carXmlDoc.SelectSingleNode("/car");
string selectionMainNode = mainNode.Attributes["name"].Value;
XmlNode colorNode = carXmlDoc.SelectSingleNode("/car/color");
string selectionColorNode = colorNode.InnerText;
XmlNode doorNode = carXmlDoc.SelectSingleNode("/car/door");
string selectionDoorNode = doorNode.InnerText;
XmlNode speedNode = carXmlDoc.SelectSingleNode("/car/speed");
string selectionSpeedNode = speedNode.InnerText;
CodeCompileUnit ccu = new CodeCompileUnit();
CodeNamespace cn = new CodeNamespace();
CodeMemberProperty cmp1 = new CodeMemberProperty();
CodeMemberProperty cmp2 = new CodeMemberProperty();
CodeMemberMethod cmm1 = new CodeMemberMethod();
cn.Imports.Add(new CodeNamespaceImport("System"));
cmp1.Name = "Color";
cmp1.Type = new CodeTypeReference(typeof(string));
cmp1.Attributes = MemberAttributes.Public;
cmp1.GetStatements.Add(new CodeSnippetExpression("return \"" +
selectionColorNode + "\""));
cmp2.Name = "Doors";
cmp2.Type = new CodeTypeReference(typeof(int));
cmp2.Attributes = MemberAttributes.Public;
cmp2.GetStatements.Add(new CodeSnippetExpression("return " +
selectionDoorNode));
cmm1.Name = "Go";
cmm1.ReturnType = new CodeTypeReference(typeof(int));
cmm1.Attributes = MemberAttributes.Public;
cmm1.Statements.Add(new CodeSnippetExpression("return " +
selectionSpeedNode));
CodeTypeDeclaration ctd = new CodeTypeDeclaration(selectionMainNode);
ctd.Members.Add(cmp1);
ctd.Members.Add(cmp2);
ctd.Members.Add(cmm1);
cn.Types.Add(ctd);
ccu.Namespaces.Add(cn);
myAb.AddCodeCompileUnit(this, ccu);
}
}
}