Sandcastle under the hood, part 1

Well, today I’ve been diving into the innards of Sandcastle. In lack of proper documentation I’ve relied on ildasm, some trace output and some common sense. Now, I don’t know how much of this that is actually correct, but I suspect that at least most of it is rather close to the truth.

Assuming you already have your compiled assemblies and documentation files the process begins with MRefBuilder. The MRefBuilder builds up an xml file by reflecting the assemblies specified on the command line. The output contains <assembly>-elements and <api>-elements. The assembly elements simply contain some meta-data about each assembly (version, description, company name et.c.). The api elements are more interesting and are categorized in groups and subgroups. Some examples of groups/subgroups are:

Group Subgroup
root
namespace
type class
type enumeration
member constructor
member method
member property
member field

Many api elements have links to other elements (i.e. a class can contain constructors, properties and methods). Some api elements are marked as pseudo=”true”, this means that they have no direct equivalent element in the actual code.
The original reflection file is enriched by applying two xsl transforms. The first one, AddOverloads.xsl, creates pseudo api-elements for grouping any overloaded methods together.

Before AddOverloads:

<api id="M:SandcastleTestLibrary.TestClass.TestOverload(System.Int32)">
...
</api>
<api id="M:SandcastleTestLibrary.TestClass.TestOverload(System.String)">
...
</api>

After AddOverloads:

<api id="Overload:SandcastleTestLibrary.TestClass.TestOverload">
...
<elements>
<element api="M:SandcastleTestLibrary.TestClass.TestOverload(System.Int32)" />
<element api="M:SandcastleTestLibrary.TestClass.TestOverload(System.String)" />
</elements>
</api>
<api id="M:SandcastleTestLibrary.TestClass.TestOverload(System.Int32)">
...
</api>
<api id="M:SandcastleTestLibrary.TestClass.TestOverload(System.String)">
...
</api>

The other transform, AddGuidFilenames.xsl, uses a hash of the unique id for each api element to create a filename in the form of a guid, this will be the filename of the final .htm file.

Next, a manifest file is created, again using an xsl transform. For each api element in the reflection.xml, a topic element is created in the manifest. The manifest, together with the sandcastle.config file is what drives the BuildAssembler. But more on that in my next post. Stay tuned for more!

Update

Also check out Part 2 and Part 3