Generating Standard XML Documentation in VB.NET

Jan 28, 11:00 pm

Article Author: Bart Gerardi
.NET 3.5 Books

Introduction


When I first learned to program, one of the principles drilled into me was the notion that code should be self-documenting; that you should be able to read code like an essay, and grasp what it was doing. This works in an academic setting, where programs are perhaps five pages of source code long, and do no more than, say, figure out how to move a dot through a maze to show that you understand how recursion works. As anyone who has programmed professionally knows, this kind of documentation is rarely possible and even if it was, may not be worth the effort.


Several years ago, someone had the more brilliant observation, "wouldn’t it be nice if the code really could document itself?" In Java the developer can insert special characters into the code, and the documentation would actually write itself. This was a boon to developers and management alike. While there is no real replacement for solidly commented code, what could be automatically generated was pretty good, and excelled at defining interfaces and contracts so that someone working in another system could get everything they needed to work with your code. Management liked it because it meant they could generate an asset off of their code base, instead of treating it as a mass of magic pudding which is what it was often considered. So, when Microsoft made the big shift into .NET, it made sense for them to carry this functionality forward.


And they did, mostly. But they only did it at first with C#, not VB. In this article, I’ll talk about how you can get this functionality into your VB.NET code, even if you are still using Visual Studio.NET 2003 and thus don’t have automatic commenting out of the box.


System Requirements


In order to benefit from this article, you should be using Visual Studio.NET 2003 to write VB.NET 1.1 code. You should also have an Internet connection and the security permissions to install the plug-in recommended below. If you are using Visual Studio 2005 or higher, you can still use some of the information in this article, but you will probably find that you don’t need it as what I discuss below is built into the IDE.


To successfully follow along with this article, you are going to need to install two different pieces of software. The first is a VisualStudio.NET plug-in called VBCommenter, which is downloadable at: http://www.gotdotnet.com/workspaces/workspace.aspx?id=112b5449-f702-46e2-87fa-86bdf39a17dd. The second piece of software is called nDoc, which is downloadable from: http://ndoc.sourceforge.net. You must install both in order for the samples to work properly.


Installing and Compiling the Sample Code


I have included a pack of samples with this article, including a VB.NET file, the XML file the VB Commenter will generate, and the final output from nDoc.


To make use of the sample code, you should install nDoc and VB Commenter from the links provided. To view the sample files, extract the download file to an empty directory. This contains two files and another zip directory. The two files are the VB.NET code that was used to generate the documentation, and the XML file that VB Commenter creates. Unzipping the second .file included in the package will create a folder called Documentation, which will contain the .chm file that makes up the documentation for the sample code as well as all the htmlhelp files that support the chm. Once compiled, the help file looks like what you see in Figure 1.



Figure 1. The generated help file


However, if you choose to compile and create the files yourself, you should first go ahead and install VBCommenter and nDoc. Once that has been done, you should create a blank solution and a blank VB.NET project of type console or whatever type you like. Add Class1.vb to your project. If you have your settings set properly (see below) upon building your solution, you will see an .xml file has been created. Now run nDoc for .NET 1.1, point it at the .dll that you just created by building your project and you’ll see a /doc directory created that contains a .chm file that appears much like the one in Figure 1.


While this process sounds manual, and for our purposes it is, you can always script nDoc to run (it has a command line interface, of course) every night, every hour, or whatever, so that your documentation automatically remains up to date.


Generating Documentation from Code


Okay, so the goal is to have our code self-documenting. There are two main customers of code comments, the next developer who works on the code, who wants to know how it works, and the guy on the outside, who simply wants to know how to call the methods and classes. While it’s important to properly document and annotate tricky or dense sections of code, this is obviously difficult to do with an automated tool. A significant gain can be made in just defining interface points, contract values, and signatures, which are much easier to document, as for those, it literally is what it is – there is no interpretation needed. Using tools in the editor and outside components you can generate this kind of documentation in a standard, distributable format, without too much effort.


To fully support this kind of IDE marked-up documentation, you need three pieces:


  • Support from the IDE

  • A comment extractor

  • A document generator

IDE Support


Until Visual Studio 2005, Microsoft supported the first two bullets above – but only in C#. The C# editor in Visual Studio acts as the first one, the developer can type the notation /// and the editor will write the information out for the developer. Consider the following small code fragment:



Public class AspToday
{ Public int wordCount(article myArticle) { Return myArticle.wordCount }
}


If the developer simply typed the notation above the words Public:



///
Public class AspToday
{ /// public int wordCount(System.Xml.XmlDocument myArticle) { return myArticle.InnerXml.Length; }
}


The editor will immediately expand them, and fill out the basic information:



/// <summary>
/// Summary for the AspToday Class
/// </summary>
public class AspToday
{ /// <summary> /// /// </summary> /// <param name="myArticle"></param> /// <returns></returns> public int wordCount(System.Xml.XmlDocument myArticle) { return myArticle.InnerXml.Length; }
}


Pretty darn handy, six key strokes from the developer and you get quite a bit of code comments put in the source for you. From the beginning, this was supported for C# in Visual Studio .NET, later on in the article I’ll show you how to get this functionality in VB.NET. The steps I show above are actually viewable on your screen: once you type the first /// the commenter engine will expand the first set immediately.


Comment Extractor


But having the comments in the code is really only half the problem, they won’t do you much good sitting in your source files. Again, Microsoft thought of this and put a setting in the C# compiler to extract the XML comments from the code and create an .xml files in the file system for later use. You select the project you wish to generate documentation for and view its properties. Under build is a checkbox to create the XML documentation as shown in Figure 2:



Figure 2. VisualStudio.NET settings for creating XML documentation


Doing this throws an XML file into the same output directory as your .dll when you build it as shown in Figure 3:



Figure 3. The generated files on the file system


Even though the VB.NET complier doesn’t do this prior to 2005, you still need the .xml files. In the next section I’ll show you how nearly the same steps above will create these files for you as well.


Document Generation


Finally, here is where C# and VB.NET meet. The next release of Visual Studio, is projected to include a project currently codenamed Sandcastle that makes all three steps are native to Visual Studio (As at present, the December CTP release of Sandcastle is currently available, see http://blogs.msdn.com/sandcastle/). But for the time being there is a 3rd-party component of choice, called nDoc. In fact, it’s so standard issue, that the comment structure above is sometimes referred to as "nDoc Comments." Sadly, nDoc, which is open-source software, is no longer being updated by its original designer. It is still being updated by the community members, and the community expects that it will continue to operate until the next generation of software can be created, possibly with Sandcastle, or perhaps some other solution.


nDoc is available at: http://ndoc.sourceforge.net/ and I wont go to deeply into how one uses it. There are plenty of places on the web that will teach you the ins and outs and nuances of how to use nDoc properly. However, the basic, manual way is to point the nDoc application either at the solution you are working on, or at the dll itself as shown in Figure 4.



Figure 4. nDoc application


Once you have nDoc installed, start up the application. If you have built your C# solution with the properties from Figure 2 set to provide the XML output, then you should be able to proceed. Select Documentation →Build and navigate either to the .dll that you want to compile documentation for, or the entire solution, depending on what you are looking to do. The nDoc software will then find all the XML files that match to either the .dll or the solution and it will generate all the output files for use in creating the .chm file. You can also choose which style to create the output as shown in Figure 4 (the Documentation Type dropdown list), I chose MSDN style, though there are others available.


To speak more generally, the VBCommenter plug-in to Visual Studio has made it easy for you to add the XML comments into your code, with the auto-expansion of the comment characters. By setting the properties in Figure 2 and compiling the solution, you have told the Visual Studio IDE to generate the XML files and leave them in the proper place on the file system. Now, I will use nDoc to pick up and compile a help file using the XML files.


This fulfills all three steps, IDE support for comment generation, something to extract the comments into files, and something to generate documentation from those files. For illustration, I’ve shown all of this using the Windows user interface version of the software. However, this is all scriptable or runnable from the command line, which makes doing all of this much easier. In addition, since it is scriptable, you can schedule it to run whenever you like.


Providing Similar Functionality in VB.NET


So, as you discovered above, you need three things to make this work – IDE support, file generation, and document production. I am still going to use nDoc for the production, one of the values of XML just being plain text is that nDoc doesn’t care how it was created. All we need to conquer is the first two of our three items.


The best way to do this is to use a Visual Studio plug-in called VBCommenter, available at: http://www.gotdotnet.com/workspaces/workspace.aspx?id=112b5449-f702-46e2-87fa-86bdf39a17dd. It’s a power toy plug-in that gives VB.NET functionality similar to what is built into C#. The most recent release at the time of writing is 1.2.6 from February 2006. You can also find significant support and help for it on the page listed above.


All you have to do is install the downloadable .msi file and it plugs itself into your Visual Studio and you’re off running. Slightly different than C#, the control panel for it lives in the tools section. Under Tools → VBCommenter Options, you’ll see:



Figure 5. VBCommenter setup


Figure 5 shows the setup options for VBCommenter. You need two things, comments in the source, and .xml files to be generated in order to use VBCommenter. VBCommenter provides two checkboxes which provide the functionality you need. It is slightly less flexible as you can’t choose to create the XML files on per-project basis, but you can change the way comments appear slightly. VBCommenter is a bit more verbose than the C# editor as using the sample code from earlier in the article and typing the VB comment character three times, ‘’‘, above the method and class yields this:



‘’‘ ————————————————————————————————————
‘’‘ Project : ClassLibrary1
‘’‘ Class : AspToday
‘’‘
‘’‘ ————————————————————————————————————
‘’‘ <summary>
‘’‘
‘’‘ </summary>
‘’‘ <remarks>
‘’‘ </remarks>
‘’‘ <history>
‘’‘ [bgerardi] 8/4/2006 Created
‘’‘ </history>
‘’‘ ————————————————————————————————————
Public Class AspToday ‘’‘ —————————————————————————————————— ‘’‘ <summary> ‘’‘ ‘’‘ </summary> ‘’‘ <param name="myArticle"></param> ‘’‘ <returns></returns> ‘’‘ <remarks> ‘’‘ </remarks> ‘’‘ <history> ‘’‘ [bgerardi] 8/4/2006 Created ‘’‘ </history> ‘’‘ ——————————————————————————————————
Public Function wordcount(ByVal myArticle As System.Xml.XmlDocument) As Integer Return myArticle.InnerXml.Length End Function
End Class


As you can see, this is quite similar to what Visual Studio does on its own with C#, and will be used to create the XML Files. Not surprisingly, when you build the solution, it puts the xml file in the same place as we seen with C# as seen in Figure 6.



Figure 6. XML documentation file on file system from VB.NET


Now, you can run nDoc with the generated XML file and generate the documentation as seen in Figure 7.



Figure 7. The VBCommenter/nDoc created help file from the VB.NET source


This file (Documentation.chm) ends up in the Doc directory, which is at the same level as the bin and obj directories as seen in Figure 8.



Figure 8. The doc directory on the file system


A Word about the Code Sample


One thing we all know about documentation is that it’s only as good as the person who writes it. While VBCommenter and Visual Studio do what they can to give the developer a good framework for commenting, it is truly up to the person at the keyboard – and not the software – to make the documentation useful. For those of you who have done a lot of reading through other people’s code, you’ll see that I’ve put in the code sample is of about average completeness. Everything is documented at least a little bit, but mostly with one or two line descriptions.


But, if you look at what was created, I suspect you’ll be amazed at what that minimal effort will get you. Not only does it give you sharp-looking documentation, but it picks up everything, from method signatures to return types, and all the comments that I added to the XML. In addition, it’s indexed, searchable, and printable. And best of all, you can keep it up to date with just a few clicks, or as I mentioned in the introduction, you can schedule it to run when you want.


What this means is that there is really no excuse to not document your classes, methods and properties, as putting in about a minute of work will yield a significant result. It remains true that the more time you put into your descriptions, the better the yield will be. However, it’s still possible to capture much of the value with very little effort, this tips the scale on the effort/reward scale more towards doing it than not, which is a positive change for any organization.


One thing that it does not do and won’t do until Microsoft releases Sandcastle, is update without developer intervention. If the developer changes the signature of a method, the documentation will remain incorrect, until the developer "resets" it. This problem exists in C# as well as VB.NET and is not related to VB Commenter, though the problem is worse in VB.NET. C# at least has some autocomplete for missing parameters and the like, while VB.NET is stuck with starting over. This is because even though the IDE supports it, what it does is actually insert the text into the file that contains the code. Once it’s wrong, the developer needs to delete it and type the comment character three times again in order to regenerate the comments. Not perfect, but like I said, the value for the effort is high enough that even having to do this every now and again makes it worth it.


The Future of Comments in Code


Microsoft has recognized a good idea when they saw it, and integrated automatic commenting functionality into the C# IDE at inception, and in VB.NET starting in 2005. Beginning with .NET 2.0 Microsoft has released public CTP versions of their code commenter, codenamed Sandcastle. Sandcastle promises to work without actually adding comments to code files, and instead using reflection to determine its information. In addition, it’ll support generics (which nDoc does not) and is going to be used to create the official .NET documentation. Unsurprisingly, the only style it’ll use is MSDN style, but perhaps having a standard for documentation isn’t a bad thing.


There are other aids on the market that do something similar, though few of them work with VB.NET well, if at all. However, one additional plug-in that helps with some of the mechanical work is called GhostDoc. It was named one of the top-10 VS.NET plug-ins of 2005, and has started supporting VB.NET "experimentally" since version 1.9.5 for VisualStudio.NET 2005. The version for Visual Studio 2003, version 1.3.0, unfortunately has no support for VB.NET. What it does is fairly clever, though it relies on you naming your methods and parameters well, as it tries to guess at your documentation based on your naming. For instance, if you have a method called GetAverageTestScore() it will add a remark that says Gets Average Test Score. While not thrilling in its semantic ability, it does a fair job of bootstrapping your documentation efforts, so that all you have to do is add in the actual value-add comments, and not the mundane, mechanical ones.


Conclusion


Generating comments from code is a three step process. Inserting the comments themselves, extracting them out, and transforming them into documentation. In this article, I discussed how a programmer does this in C#, and showed how similar, if not quite identical, features can be obtained in VB.NET.


It is particularly useful when the desired outcome, in this case, documented code, is supported by the tools themselves. C# users have always had this luxury, and now using VBCommenter, VB.NET programmers also have it. Coming soon with Sandcastle, both languages will have identical documentation strategies and will skip the first two steps entirely for method names and signatures. Of course, the details on how things actually work, such as remarks and details, will still need to be generated by the developer, as no semantic software can be made smart enough to make that work. Look for more information about that in the coming months from Microsoft.

Founders at Work

Commenting is closed for this article.