Scott Hanselman

Effective XML Document with C#, NDoc, Lutz's Documentor and the Microsoft HTML Help Workshop

June 25, '04 Comments [10] Posted in ASP.NET | Web Services | XML | Tools
Sponsored By

A lot has been said on this topic, but here's some stuff you might not know.

We use NDoc to document our API.  NDoc consumes the XML Documentation files created as a build artifact by the C# compiler. 

Most links online that talk about XML Documentation in stop at <summary> and the standard <param> stuff.  Method documentation is interesting, but the real meat happens at the top of your Class declarations.  That's where most of the prose is in MSDN documentation.  Take a look at the Remarks section of the Socket Class in the MSDN Help for example

To achieve such a rich structure, organize your XML help thusly on the top of each class declaration:

  • <Summary>
  • <Remarks>
    • <Note>(s)
  • <Example>(s)
    • <Code>
  • <SeeAlso>(s)

The XML Comment snippet below, along with NDoc produced the lovely MSDN-style documentation in the picture at right.

The <summary> tag explains the “point” of the class. A sentence or two is fine here.

/// <summary>
/// Encapsulates Thingie and a Connection to Thingie in a Service wrapper.
/// Other Services will be built with this building block.
/// </summary>

The <remarks> tag is where the real prose goes. Use this tag to describe the general use of the class, as well as any notes, gotchas, or significant design or architectural issues.

Note the use of <para> to separate paragraphs. Use <see> to refer to namespaces, classes or methods. If you don’t include the fully qualified namespace, the documenter will assume the current namespace.

/// <remarks>
/// <para>The ThingieService class contains a <see cref="IConnector"/>
/// that is pulled from the named element in the config/ThingieClient.config file. The config file
/// is loaded by <see cref="I"/>.</para>
/// <para>Note that the constructor is private, as your application gets a ThingieService by calling the static <see cref="GetThingieService"/> method.
/// From there, the ThingieService hides the <see cref="IConnector"/> and
/// is the primary interface to Thingie. The ThingieService shouldn't be used directly from an ASP.NET
/// page. Instead, it should be used from either a generated or hand-written proxy.</para>
/// <note type="note">ASP.NET developers should use <see cref="Corillian.Thingie.Security.SiteSecureThing"/> to property register a <see cref="ThingiePrincipal"/> with the system to effectively use the ThingieService.</note>
/// <para>There are two ways to call the <see cref="Execute"/> method.</para>
/// <list type="bullet">
/// <item><term>Pass in an object that implements <see cref="IRequest"/>.
/// The Thingie SessionID and UserID will be retrieved from the <see cref="ThingiePrincipal"/> on the current Thread.</term></item>
/// <item><term>Pass in an object that implements <see cref="IRequest"/> along with the Thingie SessionID and UserID as additional parameters.
/// Use this method if your Thread doesn't already have a ThingiePrincipal. One will be made for you temporarily.</term></item>
/// </list>
/// </remarks>
/// <example>
/// <code>
/// public class BankingExample
/// {
/// protected ThingieService thingie = null;
///
/// public BankingExample()
/// {
/// thingie = ThingieService.GetThingieService("BankingServiceProxy");
/// }
///
/// public virtual SignonResponse Signon(SignonRequest req, string userId, string somethingElse )
/// {
/// string sessionid = thingie.SomethingImportantToTheSession(userId);
/// string r = thingie.Execute(req, sessionid, userId);
/// SignonResponse retVal = SignonResponse.FixUpSomething(r);
/// return retVal;
/// }
/// }
/// </code>
/// </example>
/// <seealso cref="IRequest"/>
/// <seealso cref="IConnector"/>
/// <seealso cref="IConfig"/>
/// <seealso cref="ILoggingService"/>

public class ThingieService....

I also like to use Lutz Roeder's .NET Documentor to write my XML Comments in.  It has a split-pane view and a nice right-click menu that let's me see what the documentation will look like AS I TYPE.

Considering that I'd need to recompile the Application AND generate the MSDN documentation, this little tool is a big time saver.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb
Friday, 25 June 2004 01:42:24 UTC
That's great for writing XML comments, but reading XML comments in the editor is painful, and reading the rendered documentation in another window is inconvenient. I'd kill for an editor that displayed the rendered documentation in place of the XML, especially if the seealso links took you to the appropriate code...
Colin
Friday, 25 June 2004 04:59:31 UTC
Great idea! I'll start writing that tonight with CodeRush as an Add-in.
Scott Hanselman
Friday, 25 June 2004 16:35:07 UTC
I've been talking about this for a long time. It'd be nice if the IDE would have a little smart tag or toggle at the beginning of each comment section that would let you convert it back and forth between XML and rendered.
Friday, 25 June 2004 17:02:16 UTC
I was thinking - let me know what you think - that if your TEXT CURSOR was inside the doc, it would be XML, otherwise if your cursor is outside (and it's valiD XML) it will render.

Thoughts?
Scott Hanselman
Friday, 25 June 2004 18:21:39 UTC
I think I'm in the toggle camp. We're already used to expanding/collapsing blocks with toggles. Having the comments switch from rendered to XML automatically might be a bit disconcerting.
Colin
Saturday, 26 June 2004 08:38:33 UTC
Well, I've got the painting working but I'm not sure how this should behave...I mean, do we still want to write the code as XML doc? or should their be a tiny editor? Do you want the doc rendered the same font as the code, or like the MSDN help in Verdana?
Scott Hanselman
Sunday, 27 June 2004 02:11:35 UTC
I think rendering the documentation as if it were snipped from the MSDN help would make it look nice, FWIW, but it's not a deal-breaker. :)

Would it be better to make this something that can be toggled on the entire file (design view, code view, and now "documentation view") rather than something that can be toggled on individual blocks? We could leave the raw XML in code view and display the rendered XML in documentation view. If we wanted to add editing, we could add it to documentation view, and make it visual.
Colin
Sunday, 27 June 2004 02:56:17 UTC
Here's my take on what documentation view could look like.

http://homepage.usask.ca/~clc608/fcc.gif

You probably don't need to render the method signature though. :)
Colin
Sunday, 27 June 2004 18:19:45 UTC
OK...that's great for method signatures. But look at rhis post - do a class signature, they are very much different from method signatures. How should that look?

I'll work on the method sigs with your screen shot for now.

Additionally a thought/question

* I can't change the number of lines...I can only paint over the lines that exist...so, how do deal with that? Do I render in the same font size or a different one?
Monday, 28 June 2004 01:15:49 UTC
If the rendered documentation can only be as tall as the XML then this might not be workable. :/

I'm not sure which post you're referring to, but I assume the rendered class documentation would contain the summary, remarks, and the class heirarchy...
Colin
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.