Skip to content

loxsmoke/DocXml

Repository files navigation

DocXml - C# XML documentation reader

Build and test codecov NuGet version NuGet

API reference

DocXml nuget component is a small .net standard 2.0 library of helper classes and methods for compiler-generated XML documentation retrieval. XML documentation as described here https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/xmldoc/xml-documentation-comments is generated by compiler from source code comments and saved in a XML file where each documented item is identified by its unique name. These names sometimes are quite complicated especially when templates and generic types are involved. DocXml makes retrieval of XML documentation easy. For example here is the class with generic method and the piece of code that retrieves method documentation.

// Source code for XML documentation
namespace LoxSmoke.DocXmlUnitTests
{
    class MyClass2
    {
        /// <summary>
        /// TemplateMethod description
        /// </summary>
        /// <returns>Return value description</returns>
        public List<T> TemplateMethod<T>()
        { return null; }
    }
}

Fragment from DocXmlUnitTests.xml file generated by compiler.

<member name="M:LoxSmoke.DocXmlUnitTests.MyClass2.TemplateMethod``1">
    <summary>
    TemplateMethod description
    </summary>
    <returns>Return value description</returns>
</member>

Some code that retrieves XML documentation from the file and type reflection information.

// Get MethodInfo of MyClass2.TemplateMethod
var minfo = typeof(MyClass2).GetMethod("TemplateMethod");
// Load XML documentation file
DocXmlReader reader = new DocXmlReader("DocXmlUnitTests.xml");
// Get method documentation from XML file
var comments = reader.GetMethodComments(minfo);
// and print it
Console.WriteLine(comments.Summary);
Console.WriteLine(comments.Returns);

A bit more interesting example uses JsonObjectContract from Newtonsoft.Json nuget package. Here code retrieves summary comments for each property.

// Just for the sake of this example create JsonObjectContract
var jsonContract = new DefaultContractResolver().ResolveContract(typeof(MyClass2)) as JsonObjectContract;
// Load XML documentation file
DocXmlReader reader = new DocXmlReader("DocXmlUnitTests.xml");
foreach (var jsonContractProperty in jsonContract.Properties)
{
    var minfo = jsonContractProperty.DeclaringType.GetMember(jsonContractProperty.UnderlyingName)[0];
    // Get documentation from XML file
    var comments = reader.GetMemberComments(minfo);
    // and print it
    Console.WriteLine(comments.Summary);
}

Classes and methods

The main class is DocXmlReader. It reads XML file and returns documentation/comments objects.

Comment classes represent one or more comments associated with each item in the source code. Simple summary comments are returned as strings and more complex comments are returned as comments objects. Here is the list of comments classes:

  • CommonComments is the base class of all comments classes.
  • TypeComments is documentation of the class or struct.
  • MethodComments is documentation of the method, constructor, operator or property with parameter descriptions.
  • EnumComments is documentation of the Enum type. Comments of enum values are included here as well.
  • EnumValueComment is documentation of one Enum value: name, integer value and relevant documentation comments.

Static XmlDocId class is a set of static methods that generates IDs used for retrieval of documentation from XML file. This class is used by DocXmlReader.

DocXmlReader class

Constructors

There are few constructors that can be used to create DocXmlReader:

public DocXmlReader(string fileName, bool unindentText = true)
public DocXmlReader(XPathDocument xPathDocument, bool unindentText = true)

Two simplest constructors take the name of XML documentation file or constructed XPathDocument and optional indentation handling parameter. By default DocXmlReader "un-indents" comments from XML file by removing extra spaces and newline characters added by C# compiler.

public DocXmlReader(Func<Assembly, string> assemblyXmlPathFunction = null, bool unindentText = true)

This constructor should be used for retrieval of documentation for multiple assemblies. If assemblyXmlPathFunction is not specified then by default it generates XML file names by taking the assembly name and replacing it's extension with .xml. If file does not exist then empty comments object is returned by DocXmlReader. When assemblyXmlPathFunction is specified it should return the name of the XML documentation file for specified assembly. Returning null or invalid path is OK as it means that documentation for that assembly should not be loaded.

public DocXmlReader(IEnumerable<Assembly> assemblies, Func<Assembly, string> assemblyXmlPathFunction = null, bool unindentText = true)

Similar to previous constructor but here the list of assemblies can be specified during construction. In most cases DocXmlReader can find assembly documentation files automatically but in case of <inheritdoc> tag with cref there could be not enough information as to which assembly is being referred.

Documentation reading functions

There are only few functions that read documentation of types, methods and properties. Most of them do what their names say:

public MethodComments GetMethodComments(MethodBase methodInfo)
public TypeComments GetTypeComments(Type type)
public string GetMemberComment(MemberInfo memberInfo)
public CommonComments GetMemberComments(MemberInfo memberInfo)
public EnumComments GetEnumComments(Type enumType, bool fillValues = false)

Enum comment function may need some explanation though. It can return documentation for enum type and also the list of values with their names and documentation. If fillValues is false and no comments exist for any enum values then returned EnumComments.ValueComments list is empty. In other cases this list contains all values, names and value comments.

Supported documentation tags

XML Tag Attributes TypeComments class MethodComments class EnumComments class EnumValueComment class
<summary> --- Yes Yes Yes Yes
<remarks> --- Yes Yes Yes Yes
<example> --- Yes Yes Yes Yes
<param> name Yes (only for delegates) Yes No No
<typeparam> name No Yes No No
<response> code No Yes No No
<returns> --- No Yes No No
<inheritdoc> cref Yes (cref is optional) Yes (cref is optional) Yes Yes
<exception> cref No Yes No No

<Inheritdoc> tag resolution rules

<inheritdoc> tag is helpful documentation re-use tool. It can refer to the piece of documentation directly via cref attribute or can retrieve documentation for classes or methods based on resolution rules.

For type definitions (TypeComments class) presence of <summary>, <remarks>,<param> or <example> tags disables resolution. If an explicit cref attribute is specified, the documentation from the specified namespace/type/member is inherited.

  • Inherit documentation from base class working backwards up the inheritance chain.
  • Inherit documentation from all interface implementations (if any)

For methods (MethodComments class) presence of <summary>, <remarks>,<param>, <returns>,<response>,<typeparam> or <example> tags disables resolution. If an explicit cref attribute is specified, the documentation from the specified namespace/type/member is inherited.

  • For constructors search backwards up the type inheritance chain for a constructor with a matching signature. If a match is found, its documentation is inherited.

For virtual members and interface implementations:

  • If the member is an override, documentation is inherited from the member it overrides.
  • If the member is part of an interface, documentation is inherited from the interface member being implemented.

For all other items (CommonComments class) comments presence of <summary>, <remarks> or <example> tags or absence of cref attribute disables resolution. The documentation from the specified namespace/type/member is inherited.

Documentation comments examples

Simple summary comment can be located next to class definition, property, method, field, etc.

/// <summary>
/// This is class comment
/// </summary>

DocXmlReader method GetMemberComment returns this comment as string. This comment is also available as Summary property in all comments classes.

Delegate type may have comments for each parameter.

/// <summary>
/// Delegate type description 
/// </summary>
/// <param name="parameter">Parameter description</param>
public delegate void DelegateType(int parameter);

DocXmlReader method GetTypeComment returns this comment as TypeComments object with Summary property and the list of parameters as Parameters property. Parameters property is the list of tuples where Item1 is the name of the parameter and item2 is the parameter description comment.

Enum comment with documented values.

/// <summary>
/// Enum type description
/// </summary>
public enum TestEnum
{
    /// <summary>
    /// Enum value one
    /// </summary>
    Value1,
     
    /// <summary>
    /// Enum value two
    /// </summary>
    Value2
};

DocXmlReader method GetEnumComments returns this comment as EnumComments object with Summary property and the list of ValueComments. Each element in ValueComments has the name of the value e.g. Value1, actual integer value e.g. 10 and relevant comments such as summary comment of the value. If none of values has any summary comment then ValuesComments list is empty by default.

Method comment with parameters and return value.

/// <summary>
/// Member function description.
/// </summary>
/// <param name="one">Parameter one</param>
/// <param name="two">Parameter two</param>
/// <returns>Return value description</returns>
public int MemberFunction2(string one, ref int two)

DocXmlReader method GetMethodComments returns this comment as MethodComments object with Summary and Returns properties and the list of Parameters tuples. Each element in Parameters is the tuple where Item1 is the name of the parameter e.g. one and Item2 is the comment of the parameter value.

Web controller method comment with response codes.

/// <summary>
/// Member function description
/// </summary>
/// <returns>Return value description</returns>
/// <response code="200">OK</response>

DocXmlReader method GetMethodComments returns this comment as MethodComments object with Summary and Returns properties and the list of Responses tuples. Each element in Responses is the tuple where Item1 is the code of the response e.g. 200 and Item2 is the comment of the value e.g. OK.