I finished creating a code generator for Dice, and I turned the thing into a custom build task for MSBuild so I can now include Xml files in my projects and generate code from them. I had to collect and improve the informations from a variety of sources, but that made the satisfaction and sense of achievement only greater.
First, I created the code generator, using the CodeDOM model in .NET. It requires a sort of top-down approach which is untypical for .NET programming: Visual Studio and Intellisense advocate a bottom-up approach, much to Charles Petzold's chagrin. The inputs for the code generator come from data in an xml file, based on an xml schema. The intellisense in xml files with a known schema in Visual Studio 2005 rocks!
Since the xml schema and associated code classes were in a different assembly than the code generator itself, I used ILMerge to pack those assemblies together. Maybe this wasn't strictly necessary, but I figured it would be easier to use build tasks that consist of one assembly only. I integrated the ILMerge step in the build process using Jomo Fisher's instructions. Worked like a breeze.
Now came the more tricky part: adapting the project files to incorporate the new build task. I used the instructions in Dino Esposito's Cutting Edge article, but here I had to adapt and tweak. I ended up with several steps:
Register the task in the appropriate project file:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="QmlTask"
AssemblyFile="C:\Documents and Settings\dr\My Documents\<linebreak>
Visual Studio 2005\Projects\QuestMaster\Tasks\DirkRombauts.QuestMaster.Sdk.dll" />
...
</Project>
Add Target
<Project>
...
<Target Name="Qml2Code">
<QmlTask Language="CS"
FileName="%(Content.FullPath)"
OutputFileName="%(Content.FullPath).cs">
<Output TaskParameter="OutputFileName" ItemName="Qml2Code"/>
</QmlTask>
</Target>
...
</Project>
Include Qml files as content
<Content Include="yourfile.qml"/>
Update CoreBuildDependsOn
<PropertyGroup>
<CoreBuildDependsOn>
$(CoreBuildDependsOn);
Qml2Code
</CoreBuildDependsOn>
</PropertyGroup>
Last step
Build the project, then add the newly generated yourfile.qml.cs to the project, then build the project again. I couldn't figure out how to automatically include the generated file, so I settled for this manual step. Not perfect but I'm willing to live with it for now.
The next logical step in the QuestMaster SDK would be to create a custom project template to save me the hassle of adapting the project file by hand.