Chapter 9. Generating documentation – Continuous Integration in .NET

Chapter 9. Generating documentation

This chapter covers

  • Using XML documentation tags to comment code
  • Creating rich technical documentation with Sandcastle

Every developer knows another developer who doesn’t like to write documentation. Most of them see this fellow developer every day morning in the mirror; some see the other developer a little later, in the office. Even if you’re in the second group, you probably wouldn’t mind a little help on the documentation side, right?

There’s no magical way to produce documentation. It has to be written. But you can do this the smart way. How about documenting your code inside your source files and generating the documentation from there? You can do so by adding special XML comments to the code. The specially formatted tags, which you’ll learn to use in this chapter, are extracted during the build to a separate XML file. An external tool called Sandcastle can take this file and transform it into nice-looking technical documentation. Figure 9.1 illustrates the process.

In this chapter, we’ll look at how to document your code using XML notation. To do this, you’ll use Sandcastle to generate an HTML and Compiled HTML Help (CHM) format documentation. Then you’ll integrate everything into your CI process.

Figure 9.1. Generating documentation: from source code to XML, and finally to technical documentation

9.1. XML documentation

A normal comment in C# looks like this

// This is
// comment.

or like this

/* This is:
Comment */

There is a third kind of comment:

/// This is
/// comment.

This type of comment is threaded specially by the compiler. It can be extracted to a particular kind of XML file that can be used for two main purposes:

  • As a source for any kind of documentation formatting
  • By Visual Studio in IntelliSense highlighting

We’re obviously interested in the first purpose, because we want to generate nicely formatted documentation during the CI process. But let’s not forget about the IntelliSense side effect, shown in figure 9.2, which you’ll get when you’re finished.

Figure 9.2. The Visual Studio IntelliSense mechanism is based on XML documentation.

If you’re using Visual Basic, you get the same functionality with the ''' comment.

Let’s examine the commenting techniques you can use.

9.1.1. Common XML documentation tags

We’ll show you the most common XML tags used for XML documentation. For the source code, you’ll use the financial library project. It’s a perfect target for documentation, because it’s used across multiple projects as the central point for lease and loan calculations.

Let’s use the Finance class from the CiDotNet.Calc.Math namespace (it resides in CiDotNet.Calc). The XML tag you’ll use the most is shown in the following listing.

Listing 9.1. Summary XML comment tag in action

You can use the <summary> tag for various parts of your code: classes , properties, methods, enumerators , fields, constants, delegates, and so on.

If you want to comment a method or delegate in addition to using <summary>, you can use the <param> and <returns> tags, as shown here.

Listing 9.2. Commenting methods with XML comments
/// <summary>
/// Calculates the present value of an amount of
money received in the future at a given interest rate..
/// </summary>

/// <param name="compoundPeriods">Compound periods</param>
/// <param name="periodicInterestRate">Periodic interest rate</param>
/// <returns>SPPV</returns>
private static double CalculateSPPV(double compoundPeriods,
double periodicInterestRate)
{
return System.Math.Pow(1.0 + (periodicInterestRate / 100),
-compoundPeriods);
}

The <param> tag requires a name attribute, which links the description with the parameter name. The <returns> tag defines the description for the return parameter.

Some methods may throw an exception. It’s a good habit to document the possible exceptions using the <exception> tag. Doing so makes it easier for someone using this method to track down possible problems. The following listing shows an example of the <exception> tag.

Listing 9.3. Describing an exception with the cref attribute
/// <summary>
/// Gets the compound periods.
/// </summary>
/// <param name="duration">The duration.</param>
/// <param name="ppy">The ppy.</param>
/// <returns></returns>
/// <exception cref="CalcArgumentException">
if <paramref name="duration"/> or
<paramref name="ppy"/> < 1.</exception>
public static double GetCompoundPeriods(int duration, int ppy)
{
if (duration < 1)
throw new CalcArgumentException();
if (ppy < 1)
throw new CalcArgumentException();
return (double)((ppy * duration) / 12);
}

The description of the exception uses the cref attribute to create a link in the documentation to CalcArgumentException. You can also use cref attributes in other parts of your documentation. In addition, you provide some information about when the exception will be thrown. Using a <paramref> tag with a name attribute creates a link in the documentation to a given parameter.

The next commonly used XML documentation tag is <remarks>. You can apply it to classes, methods, properties, and so on. This tag usually contains additional data that’s important for the use of a given element.

Other useful tags include <example>, which is used for usage examples; and <value>, which describes a property value. Finally, the <see> tag creates a link from some text to another XML comment. The following listing contains examples of these tags.

Listing 9.4. Using <remarks>, <example>, and <see>

The <see> tag creates a link to the Mode enumerator. The examples at and give a little more information about the commented code. They contain simple text, but you can customize the documentation by formatting the text inside the elements. Let’s look at how to do this.

9.1.2. Formatting text in XML comments

If you think the XML comments aren’t readable to a normal human being, you aren’t alone. XML tagging doesn’t make the comments people-friendly. Fortunately, tools are available to create comments that are easier to read. One of them is a Visual Studio plug-in called GhostDoc (http://submain.com/GhostDoc/). You press Shift-Ctrl-D, and it reads the names of classes, methods, and parameters and automatically creates or updates the XML comments. Try it: it’s free and worth using, especially if you go a level higher and format the text inside the comments. But keep in mind that with great power comes great responsibility: it’s easy to overuse GhostDoc. You should treat the generated comments with caution. Most of them need to be edited.

For example, to format part of the text in an XML comment as code, you can use <c> (inline) and <code> (multiline), as shown here (this listing extends listing 9.4.).

Listing 9.5. Highlighting code portions in comments
/// <example>
/// Let's say you want to lease a car for 36 moths (<c>periods</c>)
/// that costs 30000 $ (<c>presentValue</c>)
/// by 7.5 interest (<c>interestRate</c>)
/// and 500 $ residual value (<c>finalValue</c>).
/// <code>CiDotNet.Calc.Math.Finance.CalculateRate(
/// 36,
/// 12,
/// 7.5,
/// 30000,
/// 500,
/// Calc.Math.Finance.Mode.BeginMode)</code>
/// Calculation mode for leasing is
(<c>Calc.Math.Finance.Mode.BeginMode</c>)
/// </example>

Both kinds of code element will be nicely formatted in the output document.

You can also introduce lists into your documentation with the <list> tab. Lists can be bulleted or numbered, or can appear in a table, as shown next.

Listing 9.6. Extended summary with a bulleted list

As we mentioned, you can use the <list> tag to create a table, but you’ll quickly reach the limit of this functionality—it only lets you create a simple table. The other option is to use the HTML <table> tag, as shown next.

Listing 9.7. Remarks for the payment mode enumerator

As you can see, you can declare HTML-style tables inside the XML documentation.

That’s nice, you say. It’s a lot of XML code in my source files. IntelliSense is handy in Visual Studio, but that’s hardly real documentation. But what if we tell you that you can generate from the XML documentation like that shown in figure 9.3?

Figure 9.3. Readable documentation that’s been transformed from XML documentation

You can create this MSDN-style documentation using Sandcastle.

9.2. Sandcastle

Sandcastle is a set of free tools from Microsoft that you can use to transform XML documentation into a formatted document. It contains a bunch of command-line programs that you can automate to create documentation, but this technique would take too long to discuss here. There’s a much quicker and more pleasant way: you can use Sandcastle Help File Builder (SHFB), which is also free. Both are available from CodePlex: Sandcastle at www.codeplex.com/Sandcastle and SHFB at http://shfb.codeplex.com/. Install both on your development machine.

Before you start, make sure Visual Studio is extracting all of your XML documentation into a single XML file. You can check this XML Documentation File setting in your project properties (see figure 9.4.).

Figure 9.4. Select the XML Documentation File check box in your project properties to make Visual Studio extract the XML documentation into a given XML file.

Visual Studio 2010 is so clever that it makes this change for you as soon you add the first /// comment to a project (provided you’ve selected the option Tools > Options > Text Editor > C# > Advanced > Generate XML Documentation Comment for ///). In earlier versions, you’ll have to select the option manually.

9.2.1. Building with Sandcastle

Start SHFB, which is essentially a GUI for Sandcastle. Using this tool, you’ll create a project file with all the necessary settings. At the end, you’ll take this file for a ride with MSBuild.

You want to be able to create documentation even on a machine that doesn’t have Sandcastle and SHFB installed. So take both installed tools and copy them to the tools directory in your project folder: put Sandcastle in tools\Sandcastle and SHFB in tools\SHFB. Remember to put in the tools directory only what’s needed—don’t clutter the project directory with unnecessary files. What you need depends on what template you’ll use to format the documentation. You can delete all the readme and help files—you don’t need them in the repository.

Start SHFB by running tools\SHFB\SandcastleBuilderGUI.exe. Add the compiled DLL and accompanying XML file to Documentation Sources in Project Explorer. Specify the obvious project properties, such as FooterText, HeaderText, HelpTitle, CopyrightText, and so on. Then get to the not-so-obvious but important properties that are important from the CI point of view; see figure 9.5 for details.

Figure 9.5. Customizing the SHFB project file

If you’re building using the Debug/Release configuration, go to the DLL and XML properties and replace the configuration name with the $(Configuration) MSBuild variable. You can use the MSBuild variables because the SHFB project files are in fact MSBuild scripts. One important project property you have to set is SandcastlePath: set it to $(MSBuildProjectDirectory)\tools\Sandcastle\. It’ll use the MSBuild predefined variable to build an absolute path to the Sandcastle binaries.

You need to set one more property in order for the documentation process to work on a machine that doesn’t have Sandcastle installed. In Project Properties, locate UserDefinedProperties, and click the ... button. Figure 9.6 shows the dialog box that opens.

Figure 9.6. Setting the SHFBROOT variable in the SHFB user-defined properties dialog box

Thanks to the SHFBROOT variable, MSBuild tasks can locate the SHFB installation for any necessary files.

There’s no way to document the namespace using the XML documentation. Even if you use the <summary> tag on a namespace, it’ll be ignored by the compiler, and it won’t be added to the XML file. You can close this gap by documenting the namespace in the SHFB GUI. In Project Properties, locate the Namespace Summaries property, and open it. Figure 9.7 shows the dialog box in which you can add the summaries.

Figure 9.7. Editing summaries on namespaces. To include them in your documentation, you have to use SHFB.

You can browse the other properties, such as HelpFileFormat. By default, you’re generating an HtmlHelp file. But you can change it to a website if you want to deploy the documentation to a web server for immediate viewing. And look at the PresentationStyle property: you can dress up your documentation in various ways. Visibility lets you choose which filters to use on the documentation elements.

When you’re ready, click the Build the Help File icon on the SHFB toolbar to make a test run. SHFB will switch to the Build Output window and create the documentation. You can look in the Help directory for a Documentation.chm file (figure 9.8 shows the file’s content).

Figure 9.8. A CHM file created from XML documentation using Sandcastle

You now have nice-looking HtmlHelp documentation. You’re ready to make documentation creation part of your CI process.

9.2.2. Sandcastle in CI

Before you add Sandcastle documentation generation to the CI server, you have to automate it. This task is easy. As we said earlier, an SHFB project file is in fact an MSBuild script. All you have to do to create documentation is add a task like this to build.proj:

<Target Name="Document" >
<MSBuild Projects="CiDotNet.shfbproj"/>
</Target>

That’s it. If you hook up the new target to run during an automated build and check everything in to the repository, your build server should snap right in. You’ll get the CHM file on the server. Now you need to do something useful with it: send it over email, copy it to a location where it’ll be available for everyone, or add it to the deployment package (we’ll deal with deployment in the next chapter).

But here, let’s do something different. How about generating the documentation and integrating the results with the TeamCity CI server? Change the type of generated documentation to Website (the HelpFileFormat property in SHFB Project Properties).

Getting the documentation to be visible on the build-information page in Team-City is straightforward. Go to your TeamCity project’s General Settings, and set the Artifacts path to

Help/**/* => Help

This causes all the Help folder content from the current build to be copied to the Help artifacts folder. To make the documentation visible on the build-report page, add a new tab in the server configuration, pointing to /Help/Index.html. After a successful build, you should see something like figure 9.9.

Figure 9.9. Sandcastle-generated documentation integrated with TeamCity build report page

You should consider two things when you incorporate Sandcastle into CI. First, as you can see, generating documentation files with Sandcastle takes time. Even for a tiny project, it can take a few minutes. If you feel it’s taking too long, consider moving the documentation build out of CI and into the daily build.

The second issue is the size of the artifacts. If you store every documentation drop, you’ll need to consider the amount of hard drive space required.

9.3. Summary

It’s maybe a truism, but well-documented code is more valuable and more maintainable than code with neglected documentation. Knowing the reason code was written one way and not another way makes a difference. Good documentation will make it easier for you or anyone else to understand the code later and to fix bugs. And by commenting your code, you can get help such as IntelliSense in Visual Studio, which means you can develop more quickly.

Using tools like Sandcastle, you can generate nice-looking, readable documentation in the form of Windows Help files or a website. The process can be automated and incorporated into CI. This way, you’ll always have up-to-date, code-level documentation available.

You can add documentation generated this way to your software, in a step we’ll look at in the next chapter: deployment.