A static Documentation class.

A Documentation Class Convention

It can be hard to know what a namespace is supposed to do.

However, if you start putting a static class called “Documentation” in each of your projects, you can use the same integrated documentation display features in Visual Studio that you use for code to see documentation on your namespaces and libraries.

Let's take a look.

Integrated Documentation in Visual Studio

One of the best features of Visual Studio is being able to see code documentation directly in the Visual Studio editor, with Visual Studio even showing this information in several different ways! Let’s take a look.

Intellisense - The summary of member documentation is shown alongside each option in the intellisense dropdown that appears as you type:

Intellisense of String.Compare()

Note that method parameter documentation is also shown for each parameter as you fill them in. <chef’s kiss!>

Hover - Additional elements of member documentation are shown when you mouse-hover over a member:

Mouse-Hover of String.Compare()

Go To Definition - Visual Studio will regenerate the documentation for any member and display it as a comment:

Go To Definition of String.Compare()

It is hard to express just how helpful this supply of integrated documentation can be! It means you don’t have to “break-flow” to go look up the details of a candidate function on a website. It means you can arrow through all the available methods of a type, or narrow your search using a few letters. It means you can read about parameters and return types as you are using them.

This information is so useful, it’s not just limited to Visual Studio. Many other development tools provide the same features.

For all of these approaches, documentation is sourced from the XML documentation comments C# allows on each member:

/// <summary>
/// "*", asterix
/// </summary>
public static readonly object ForAsterix;

But there is a problem: how can we document a namespace?

Documentation for a Namespace?

First of all, why would you want documentation for a namespace?

Well at some point you might find yourself looking at a bunch of using directives:

using D8S.L0000.L001.Extensions;
using R5T.L0066.Extensions;
using R5T.T0246;
using F10Y.T0005;
using F10Y.T0011;

And start wondering, what the heck do all of them do?!

If you try to use any of the ways Visual Studio displays information for non-namespace members, you are out of luck: namespaces cannot have XML documentation comments. Which means there is no source of documentation for Visual Studio to use, and that means there is no display of namespace documentation in Visual Studio. So sad.

Wouldn’t it be nice if namespaces could have documentation?

Other Approaches

Some work around include:

  • Using a README.md file - but this is not integrated at all, so you will have to break-flow to go find it.
  • Add a regular comment in a source code file somewhere - but when you are using a compiled binary, like a Nuget package, where will you ever see a comment in the source code?
  • XML documentation on a type within the namespace - sure, but which type?

Of these, it is the last option that is the most interesting. What if we could define a convention that a specific type is always labeled?

A .NET Project Convention

I always put a static documentation class in each of my projects:

Intellisense of String.Compare()

And it looks like this:

namespace R5T.L0090.T000
{
    /// <summary>
    /// Simplified IEqualityComparer types library.
    /// </summary>
    public static class Documentation
    {
    }
}

The documentation always has the same value as the project file <Description> property file, i.e. the value used by the NuGet package manager:

<Project>Sdk="Microsoft.NET.Sdk"</Project>
  <PropertyGroup />
    <Description>Simplified IEqualityComparer types library.</Description>
	...

This means our using directives from above can be suffixed with an XML comment referencing the documentation class:

using D8S.L0000.L001.Extensions; /// <see cref="D8S.L0000.L001.Documentation" />
using R5T.L0066.Extensions; /// <see cref="R5T.L0066.Documentation" />
using R5T.T0246; /// <see cref="R5T.T0246.Documentation" />
using F10Y.T0005; /// <see cref="F10Y.T0005.Documentation" />
using F10Y.T0011; /// <see cref="F10Y.T0011.Documentation" />

And when you mouse-hover over the documentation class, you see documentation for the namespace:

Go To Definition of String.Compare()

Voila!

One last point: what if you want integrated documentation for a library, or an assembly, and not just a namespace? In this case I have nothing for you. You need to go elsewhere to refer to documentation, perhaps online. But if you have a namespace with the same name as the library, isn’t that the same thing? Also, there is no reason you cannot have static Documentation classes for each namespace within a library.

This really is a useful technique.

Disable Warning CS1587

Warning! If you try this, you will probably be greeted by the annoying CS1587: “XML comment is not placed on a valid language element” warning:

Go To Definition of String.Compare()

Which I generally turn off at the project level using the project <NoWarn> property:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <NoWarn>1587</NoWarn>
	...

Yes, there is always a risk in turning off warnings, but I myself have never encountered a downside. If you are really a stickler, you can always just suppress the warning at the code site itself:

Go To Definition of String.Compare()

Conclusion

Always create a static class in your projects that is named “Documentation” by convention. You can thank me later!