This documentation is archived and is not being maintained.

Generating Documentation for Your Visual Basic .NET Applications

Visual Studio .NET 2003
 

Wei-Meng Lee
Developer Learning Solutions

January 2005

Summary: Learn how to use a freely available PowerToy to add XML documentation support to your Visual Basic .NET application and create documentation as you write your code. (17 printed pages)

Contents

Introduction
Inline Documenting Using VBCommenter
Generating the Documentation
Conclusion

Introduction

Documenting your code is often the last thing you would do in your typical project cycle. While the importance of writing documentation has been stressed umpteen times, developers usually devote the best part of the project cycle to building new features, and then finally doing a mediocre job at the end writing the dreaded documentation. Borrowing the popular clean as you go phrase found in a lot of kitchens, the best way to churn out top quality documentation for your project would be to document as you go.

In Visual Studio .NET 2003, XML code documentation is supported in C#, but not in Visual Basic .NET. However, you can download a free plug-in known as VBCommenter PowerToy to enable XML in-line documenting in Visual Studio .NET 2003. You can download VBCommenter at http://www.gotdotnet.com/workspaces/workspace.aspx?id=112b5449-f702-46e2-87fa-86bdf39a17dd.

Inline Documenting Using VBCommenter

To see how VBCommenter works, let's create a new Class Library project in Visual Studio .NET 2003, as shown in Figure 1. I will create a class definition and then add XML documentation to it.

Figure 1. Creating a new class library project

For this example, I have defined a simple Point. Once you've installed VBCommenter, you can insert an XML comment by typing three apostrophes (') before a class definition, property, member variables, or method (see Figure 2).

Figure 2. Adding XML comments to your code

When you press Enter, the XML document template shown in Figure 3 is automatically generated for you.

Figure 3. The XML comment template generated

You can configure the settings of VBCommenter by going to Tools -> VBCommenter Options (see Figure 4).

Figure 4. Configuring the VBCommenter

Listing 1 at the end of this article shows the full XML documentation for the Point class. I will highlight some of the important points here.

You can get a list of XML documentation tags from MSDN at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vclrfTagsForDocumentationComments.asp. Here is the list:

  • <c>
  • <para>
  • <see>
  • <code>
  • <param>
  • <seealso>
  • <example>
  • <paramref>
  • <summary>
  • <exception>
  • <permission>
  • <value>
  • <include>
  • <remarks>
  • <list>
  • <returns>

As an example, let's examine the documentation I have done for one of the overloaded methods:

    ''' <overloads>
    ''' Calculates the distance between two points
    ''' </overloads>
    ''' 
    ''' <summary>
    ''' Calculates the distance of a point from the origin
    ''' </summary>
    ''' 
    ''' <returns>The distance between the current point and the origin
    ''' </returns>
    ''' <example> This sample shows how to call the <c>length()</c> 
    ''' method
    ''' <code>
    '''    Dim ptA As New Point(3, 4)
    '''    Dim distance As Single = ptA.length()
    ''' </code>
    ''' </example>
    ''' 
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    '''    [Wei-Meng Lee]   9/27/2004   Created
    ''' </history>

You will notice that there is a new element—<overloads>—that is not in the list specified in the MSDN documentation. The <overloads> element is used to give a general description for methods that are overloaded. You will see the effect of this element later when we generate the documentation using the NDOC tool) Note that you only need to specify the <overloads> element on only one (any one will do) of the overloaded methods.

You can also include code samples in your documentation using the <example> tag. To format a word (or sentence) as code, use the <c> tag. For multiple lines of code, use the <code> tag.

Because the XML comments that you add to your code may make reading it difficult, you can hide the comments by clicking on the "-" minus sign on the left of the code window. To reveal the documentation, click the "+" plus sign as shown in Figure 5.

Figure 5. Hiding the comments

Once you have commented your code, rebuild your class(es) and you will be able to find an XML document with the same name as your project in the bin folder of your project. Figure 6 shows the structure of the XML document.

Click on image to see a larger version

Figure 6. The XML document generated by VBCommenter

Generating the Documentation

With the XML documentation generated by VBCommenter, you now have two options in terms of documentation:

  1. Write your own XSLT transformation stylesheets to transform the XML document into a readable format such as HTML, PDF, and so on.
  2. Use a third-party tool to automatically parse the XML documentation into the various documentation formats it supports.

I prefer the second option and use NDoc (http://ndoc.sourceforge.net/), a code documentation generator for .NET. NDoc is a free, open-source tool that generates documentation in several different formats, including the MSDN-style HTML Help format (.chm), the Visual Studio .NET Help format (HTML Help 2), and MSDN-Online style Web pages.

The current version of NDoc is version 1.3 (in beta). You can install NDoc to target different versions of .NET—Mono, .NET 1.0, or .NET 1.1. I chose the .NET 1.1 target as I am using Microsoft Visual Studio .NET 2003.

Once NDoc is installed, you should see the window shown in Figure 7 when the application is launched. You can choose the type of documentation you want to generate by selecting the documentation type in the drop-down listbox.

Figure 7. Launching NDoc

Click on Add to add the assembly filename (see Figure 8). Once the assembly is selected (MyPoint.dll in the bin folder, in my case), the XML document filename field is automatically completed (same name as the assembly, but with an .XML extension).

Figure 8. Adding an assembly to NDoc

You can add multiple projects into the same documentation by adding each assembly into the NDoc project.

Once you are ready to build the documentation, click on the Build Documentation button in the toolbar as illustrated in Figure 9.

Figure 9. Building the documentation

To view the documentation, click on the View Documentation button in the toolbar (Figure 10).

Figure 10. Viewing the documentation

You should see the documentation generated as shown in Figure 11 (I have expanded on the tree in the left pane to reveal the full documentation).

Figure 11. The MSDN-style documentation generated

Let's zoom in on the documentation generated by the documentation tags that we discussed earlier. In particular, let's see the documentation for the overloaded length() method as illustrated in Figure 12.

Figure 12. Comparing the XML tags and the actual documentation generated

As you can see, the text in the <overloads> element is used to provide a general description for the overloaded method, while the actual description for each overloaded method is described by the <summary> element. If you do not use the <overloads> tag for any of the overloaded methods, NDoc will use the text found in the first <summary> element as the general description of the overloaded methods.

Click on the first overloaded method of the length() method and see the relationship between the documentation tag and the actual documentation as shown in Figure 13.

Figure 13. Comparing the XML tags and the actual documentation generated

Note that the <remarks> element is empty and will result in an empty Remarks section in the documentation. If you leave out the <remarks> element, the Remarks section is not generated.

Distributing the Documentation

If you look into the properties section in NDoc, you specify the location of the generated documentation by changing the OutputDirectory attribute. In Figure 14, my documentation would be saved in the c:\documentation folder.

Figure 14. Configuring the output directory for the documentation

Once you have built the documentation, you can view the list of files generated in Figure 15.

Figure 15. Viewing the generated documentation

If you want to distribute the documentation for your class, you simply need to distribute the file with the .chm extension. This is the compiled HTML help and it does not require the other HTML files generated in the same folder.

Conclusion

In this article, you have seen how you can add XML comments in your Visual Basic .NET applications, and then use a third-party tool to generate documentations for your application. All the tools covered in this article are free, so it's a great way to start documenting your applications. If you have other favorite tools for generating code documentation, be sure to share them with me at wei_meng_lee@hotmail.com.

Wei-Meng Lee (Microsoft .NET MVP, Singapore) is a technologist and founder of Developer Learning Solutions, a technology company specializing in hands-on training on the latest Microsoft technologies. Wei-Meng speaks regularly at international conferences and has authored and coauthored numerous books on .NET, XML, and wireless technologies, including Windows XP Unwired and the .NET Compact Framework Pocket Guide (both from O'Reilly Media, Inc). He writes extensively for the O'Reilly Network on topics ranging from .NET to Mac OS X.

Listing 1

''' -----------------------------------------------------------------------------
''' Project    : MyPoint
''' Class    : Point
''' 
''' -----------------------------------------------------------------------------
''' <summary>
''' The Point class contains 2 properties, 1 overloaded constructor, and 
''' 1 overloaded method
''' </summary>
''' <remarks>
''' If you need to use the Point class in the System.Drawing namespace, be 
''' sure to reference it using the fullname, i.e. System.Drawing.Point
''' </remarks>
''' <history>
'''    [Wei-Meng Lee]   9/26/2004   Created
''' </history>
''' 
''' -----------------------------------------------------------------------------
Public Class Point
    Private ptX, ptY As Integer
    Private Shared count As Integer

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Empty constructor
    ''' </summary>
    ''' <remarks>
    ''' Creates a new instance of the Point class
    ''' </remarks>
    ''' <history>
    '''    [Wei-Meng Lee]   9/26/2004   Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub New()
        count += 1
    End Sub

    ''' -----------------------------------------------------------------------------
    ''' <overloads>
    ''' Constructor
    ''' </overloads>
    ''' <summary>
    ''' Constructor with two parameters
    ''' </summary>
    ''' <param name="x"></param>
    ''' <param name="y"></param>
    ''' <remarks>
    ''' Creates a new instance of the Point class
    ''' <para>
    ''' Parameter x is assigned to the x-coordinate and 
    ''' Parameter y is assigned to the y-coordinate 
    ''' </para>
    ''' </remarks>
    ''' <history>
    '''    [Wei-Meng Lee]   9/26/2004   Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub New(ByVal x As Integer, ByVal y As Integer)
        ptX = x
        ptY = y
        count += 1
    End Sub

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Property for x-coordinate
    ''' </summary>
    ''' <returns>The x-coordinate</returns>
    ''' <history>
    '''    [Wei-Meng Lee]   9/26/2004   Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Property x() As Integer '   sets the X coordinate
        Get
            Return ptX
        End Get
        Set(ByVal Value As Integer)
            If Value < 500 And Value > -500 Then
                ptX = Value
            End If
        End Set
    End Property

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Property for y-coordinate
    ''' </summary>
    ''' <returns>The y-coordinate</returns>
    ''' <history>
    '''    [Wei-Meng Lee]   9/26/2004   Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Property y() As Integer '   sets the Y coordinate
        Get
            Return ptY
        End Get
        Set(ByVal Value As Integer)
            ptY = Value
        End Set
    End Property
    ''' -----------------------------------------------------------------------------
    ''' <overloads>
    ''' Calculates the distance between two points
    ''' </overloads>
    ''' 
    ''' <summary>
    ''' Calculates the distance of a point from the origin
    ''' </summary>
    ''' 
    ''' <returns>The distance between the current point and the origin
    ''' </returns>
    ''' <example> This sample shows how to call the <c>length()</c> 
    ''' method
    ''' <code>
    '''    Dim ptA As New Point(3, 4)
    '''    Dim distance As Single = ptA.length()
    ''' </code>
    ''' </example>
    ''' 
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    '''    [Wei-Meng Lee]   9/27/2004   Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function length() As Single
        Return Math.Sqrt(Math.Pow(ptX, 2) + _
               Math.Pow(ptY, 2))
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Calculates the distance of a point from another point
    ''' </summary>
    ''' 
    ''' <param name="pointOne">A Point object</param>
    ''' <returns>The distance between the current point and the 
    ''' specified point
    ''' </returns>
    ''' 
    ''' <example> This sample shows how to call the <c>length()</c> method 
    ''' with a point specified
    ''' <code>
    '''    Dim ptA As New Point(3, 4)
    '''    Dim ptB As New Point(7, 8)
    '''    Dim distance As Single = ptA.length(ptB)
    ''' </code>
    ''' </example>
    ''' <remarks>
    ''' 
    ''' </remarks>
    ''' 
    ''' <history>
    '''    [Wei-Meng Lee]   9/27/2004   Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function length(ByVal pointOne As Point) As Single
        Return Math.Sqrt(Math.Pow(ptX - pointOne.x, 2) + _
               Math.Pow(ptY - pointOne.y, 2))
    End Function

End Class

Show: