Inherit XML comments in your C# source code.
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.
Here are a few examples of your XML comments with and without InheritDoc...
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();
}
<members>
<member name="M:MyDatabase.DoSomething">
<summary>
A long detailed description about this method
</summary>
</member>
<-- Nothing generated for MyCoolDatabase.DoSomething() -->
</members>
<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>
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 {
}
<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>
<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.
public interface IDatabase {
/// <summary>
/// A long detailed description about this method
/// <summary>
void DoSomething();
}
public class MyCoolDatabase : IDatabase {
/// <inheritdoc/>
public override void DoSomething();
}
<members>
<member name="M:IDatabase.DoSomething">
<summary>
A long detailed description about this method
</summary>
</member>
<-- Nothing generated for MyDatabase.DoSomething() -->
</members>
<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>
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();
}
<members>
<member name="M:MyDatabase.RunSomething">
<summary>
A long detailed description about this method
</summary>
</member>
<-- Nothing generated for MyDatabase.RunSomethingAsync() -->
</members>
<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>
InheritDoc is available in three flavors...
Install-Package InheritDoc
.\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.
dotnet tool install -g InheritDocTool
InheritDoc
Tip: Run with a --help switch to see a list of command line switches available.
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
namespace InheritDocTest {
/// <summary>
/// ClassA Summary
/// </summary>
public class ClassA {
}
/// <inheritdoc/>
public class ClassB : ClassA {
}
}
<?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>
<?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.
Here are the recommended steps to do a release of your product with the appropriate documentation...
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)
InheritDoc uses the Apache License 2.0.
Contact me at kent@fireshark.com if you have any questions, concerns, or ideas.
Copyright 2017-2018, Fireshark Studios, LLC