InheritDoc

Inherit XML comments in your C# source code.

Build a real-time web app using C# on the server and Vue.js on the client -- checkout Butterfly Server .NET on GitHub

Overview

InheritDoc allows adding <inheritdoc/> tags to XML comments in C# source code to inherit XML comments from base classes, interfaces, and similar methods. This eliminates unwanted copying and pasting of duplicate XML comments and automatically keeps XML comments sychronized.

XML comments (starting with ///) are compiled into XML documentation files for each assembly by the normal build process. InheritDoc post processes these XML documentation files to inherit XML comments as needed. This approach makes the XML comments compatible with other documentation tools, accessible by Intellisense in compiled packages, and packagable into a Nuget package if distributing a library.

Key Usage Scenarios

Examples

Here are a few examples of your XML comments with and without InheritDoc...

Your C# Code
public abstract class MyDatabase {
    /// <summary>
    /// A long detailed description about this method
    /// <summary>
    public abstract void DoSomething();
}

public class MyCoolDatabase : MyDatabase {
    /// <inheritdoc/>
    public override void DoSomething();
}
XML documentation file without InheritDoc
<members>
    <member name="M:MyDatabase.DoSomething">
        <summary>
            A long detailed description about this method
        </summary>
    </member>
    <-- Nothing generated for MyCoolDatabase.DoSomething() -->
</members>
XML documentation file with InheritDoc
<members>
    <member name="M:MyDatabase.DoSomething">
        <summary>
            A long detailed description about this method
        </summary>
    </member>
    <member name="M:MyCoolDatabase.DoSomething">
        <summary>
            A long detailed description about this method
        </summary>
    </member>
</members>
Your C# Code
public abstract class MyDatabase {
    /// <summary>
    /// This will do something
    /// <summary>
    public void DoSomething() {
    }

    /// <summary>
    /// This will run something
    /// <summary>
    public void RunSomething() {
    }
}

/// <inheritdoc/>
public class MyCoolDatabase : MyDatabase {
}

/// <inheritdoc/>
public class MyReallyCoolDatabase : MyCoolDatabase {
}
XML documentation file without InheritDoc
<members>
    <member name="M:MyDatabase.DoSomething">
        <summary>
            This will do something
        </summary>
    </member>
    <member name="M:MyDatabase.RunSomething">
        <summary>
            This will run something
        </summary>
    </member>
    <-- Nothing generated for MyCoolDatabase.DoSomething() -->
    <-- Nothing generated for MyCoolDatabase.RunSomething() -->
    <-- Nothing generated for MyReallyCoolDatabase.DoSomething() -->
    <-- Nothing generated for MyReallyCoolDatabase.RunSomething() -->
</members>
XML documentation file with InheritDoc
<members>
    <member name="M:MyDatabase.DoSomething">
        <summary>
            This will do something
        </summary>
    </member>
    <member name="M:MyDatabase.RunSomething">
        <summary>
            This will run something
        </summary>
    </member>
    <member name="M:CoolDatabase.DoSomething">
        <summary>
            This will do something
        </summary>
    </member>
    <member name="M:CoolDatabase.RunSomething">
        <summary>
            This will run something
        </summary>
    </member>
    <member name="M:ReallyCoolDatabase.DoSomething">
        <summary>
            This will do something
        </summary>
    </member>
    <member name="M:ReallyCoolDatabase.RunSomething">
        <summary>
            This will run something
        </summary>
    </member>
</members>

Also note that if the <inheritdoc> tag is at the class or interface level then all member comments are automatically inherited without needing to specify an <inheritdoc> tag on each member.

Your C# Code
public interface IDatabase {
    /// <summary>
    /// A long detailed description about this method
    /// <summary>
    void DoSomething();
}

public class MyCoolDatabase : IDatabase {
    /// <inheritdoc/>
    public override void DoSomething();
}
XML documentation file without InheritDoc
<members>
    <member name="M:IDatabase.DoSomething">
        <summary>
            A long detailed description about this method
        </summary>
    </member>
    <-- Nothing generated for MyDatabase.DoSomething() -->
</members>
XML documentation file with InheritDoc
<members>
    <member name="M:IDatabase.DoSomething">
        <summary>
            A long detailed description about this method
        </summary>
    </member>
    <member name="M:MyCoolDatabase.DoSomething">
        <summary>
            A long detailed description about this method
        </summary>
    </member>
</members>
Your C# Code
public abstract class MyDatabase {
    /// <summary>
    /// A long detailed description about this method
    /// <summary>
    public abstract void RunSomething();

    /// <inheritdoc cref="MyDatabase.RunSomething"/>
    public abstract Task RunSomethingAsync();
}
XML documentation file without InheritDoc
<members>
    <member name="M:MyDatabase.RunSomething">
        <summary>
            A long detailed description about this method
        </summary>
    </member>
    <-- Nothing generated for MyDatabase.RunSomethingAsync() -->
</members>
XML documentation file with InheritDoc
<members>
    <member name="M:MyDatabase.RunSomething">
        <summary>
            A long detailed description about this method
        </summary>
    </member>
    <member name="M:MyDatabase.RunSomethingAsync">
        <summary>
            A long detailed description about this method
        </summary>
    </member>
</members>

Getting Started

InheritDoc is available in three flavors...

  1. The InheritDoc nuget package installs a .NET Framework EXE that can be run from a command prompt
  2. The InheritDocTool nuget package installs as a .NET Core global tool
  3. The InheritDoc Visual Studio Extension installs as an extension into Visual Studio

InheritDoc

  1. Install InheritDoc in your solution by entering this in the Package Manager Console...
    Install-Package InheritDoc
  2. Run InheritDoc by entering this in the Package Manager Console...
    .\packages\InheritDoc.2.0.2\tools\InheritDoc

    -or-

    \Users\<your user name>\.nuget\packages\inheritdoc\2.0.2\tools\InheritDoc.exe

    The path depends on the type of project (.NET Framework vs .NET Standard/Core).

Tip: Run with a --help switch to see a list of command line switches available.

InheritDocTool

  1. Install InheritDoc as a .NET Core global tool by executing in Package Manager Console...
    dotnet tool install -g InheritDocTool
  2. Run InheritDocTool by entering this in the Package Manager Console...
    InheritDoc

Tip: Run with a --help switch to see a list of command line switches available.

InheritDoc Visual Studio Extension

  1. Install InheritDoc Visual Studio Extension from here
  2. Run InheritDoc manually by choosing Tools > Run InheritDoc now from the Visual Studio menu

    -OR-

    Change the mode to Automatic (under Tools > Options > InheritDoc and InheritDoc will run automatically after each solution build

Trying on a Sample Project

  1. Create a new Class Library Project in Visual Studio called InheritDocTest
  2. Add these classes to Program.cs...
    namespace InheritDocTest {
        /// <summary>
        /// ClassA Summary
        /// </summary>
        public class ClassA {
        }
    
        /// <inheritdoc/>
        public class ClassB : ClassA {
        }
    }
    
  3. Right click the InheritDocTest project, click Properties, click Build, and check the XML documentation file checkbox
  4. Click Build > Rebuild Solution menu item
  5. Open InheritDocTest/bin/Debug/InheritDocTest.xml and confirm it looks like...
    <?xml version="1.0" ?>
    <doc>
        <assembly>
            <name>InheritDocTest</name>
        </assembly>
        <members>
            <member name="T:InheritDocTest.ClassA">
                <summary>
                    ClassA summary
                </summary>
            </member>
            <member name="T:InheritDocTest.ClassB">
                <inheritdoc />
            </member>
        </members>
    </doc>
    
  6. Now run either the InheritDoc Command Line Tool or InheritDoc Visual Studio Extension on this project and confirm a new InheritDocTest/bin/Debug/InheritDocTest.new.xml file looks like...
    <?xml version="1.0" encoding="utf-8" ?>
    <doc>
        <assembly>
            <name>InheritDocTest</name>
        </assembly>
        <members>
            <member name="T:InheritDocTest.ClassA">
                <summary>ClassA summary</summary>
            </member>
            <member name="T:InheritDocTest.ClassB">
                <summary>ClassA summary</summary>
            </member>
        </members>
    </doc>
    

Notice the <inheritdoc/> has been replaced with the parent class comments as expected.

To overwrite the original .xml files, run the InheritDoc Command Line Tool with a -o switch or change the InheritDoc Visual Studio Extension options (under Tool > Options > InhertiDoc) to overwrite existing files.

Recommended Release Process

Here are the recommended steps to do a release of your product with the appropriate documentation...

  1. Build your project as normal
  2. Run InheritDoc to rewrite the XML documentation files replacing <inheritdoc/> tags with the appropriate XML comments
  3. Run your favorite documentation generator (like XmlDocMarkdown or DocFx) to generate your HTML or Markdown documentation
  4. Publish your new HTML or Markdown documentation (perhaps pushing Markdown documentation to your Github repository)
  5. Build and publish your NuGet package (the updated XML documentation files will allow users to see the right Intellisense tips)

FAQ

Does InheritDoc modify my source code?

No, InheritDoc modifies the XML documentation files associated with your assembly instead of modifying the source code


Does InheritDoc allow Visual Studio Intellisense to have the right comments?

InheritDoc does not help Intellisense to show the right comments when you have the source files open (Visual Studio doesn't read the modified XML documentation files when the source files are available).

InheritDoc does allow Intellisense to show the right comments from binary references that have modified XML documentation files (like binary references in NuGet packages).


Does InheritDoc integrate with Visual Studio?

InheritDoc is available as a command line tool (install via NuGet) and available as a Visual Studio extension (install from Visual Studio Marketplace). The command line tool does not integrate with Visual Studio. The Visual Studio extension does integrate with Visual Studio.


How can I inherit the comments for a System class (like System.Exception)?

Use the -g switch with a comma delimited list of the source XML documents for the appropriate System classes (like -g"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.X\mscorlib.xml").


I'm using a -g switch to extend the documentation on a System class, how can I exclude the XML comments for System.Object?

Use the -x switch with a comma delimited list of classes to exclude from inheriting from (like -xSystem.Object)

Release Notes

Licensing

InheritDoc uses the Apache License 2.0.

Contact Me

Contact me at kent@fireshark.com if you have any questions, concerns, or ideas.

Build a real-time web app using C# on the server and Vue.js on the client -- checkout Butterfly Server .NET on GitHub

Copyright 2017-2018, Fireshark Studios, LLC