Click here to Skip to main content
13,448,170 members (53,519 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


3 bookmarked
Posted 23 Apr 2014

Automatic Code Documentation Based on Your C# Comments

, 23 Apr 2014
Rate this:
Please Sign up or sign in to vote.
Automatic code documentation based on your C# comments

I’ve written a few APIs over the years and the worst part is writing the documentation:

  • It takes extra time
  • It must be updated every time you make changes to your code
  • It is a duplication of work because I already document my code inline anyway

So, here’s a handy utility I wrote which will use reflection to whip through your code and draw out the comments.

Generating XML Documentation

Before proceeding, you must setup your project to generate an XML file of your code comments. This is done via the Properties –> Build menu in your project (presumably it’s a web project). See this screenshot below:


This generates an XML file in the bin directory every time you build. The file contains all your code comments, ready for parsing by my helper utility. The format is something like this:


So, with this in place, here is the utility class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Xml;
using System.Xml.Linq;
using Common;

namespace Web.Code
    /// <summary>
    /// Creates documentation for our various API methods
    /// </summary>
    public class ApiDocumentationGenerator
        #region Sub classes

        public class Parameter
            public string Name { get; set; }
            public string Type { get; set; }
            public string Description { get; set; }

        public class Method
            public string Name { get; set; }
            public List<Parameter> Parameters = new List<Parameter>();
            public string Summary { get; set; }


        #region Properties

        public List<Method> Methods = new List<Method>();
        private string PathToXmlDocumentation = "";

        private XDocument _XmlDocumentation = null;
        private XDocument XmlDocumentation
                if (_XmlDocumentation == null)
                    _XmlDocumentation = XDocument.Load(this.PathToXmlDocumentation);
                return _XmlDocumentation;


        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="pathToXmlDocumentationFile"></param>
        public ApiDocumentationGenerator(string pathToXmlDocumentationFile)
            this.PathToXmlDocumentation = pathToXmlDocumentationFile;

        /// <summary>
        /// Generates our classes
        /// </summary>
        public void Generate()
            // BaseController is a class I wrote which all my MVC *Controller 
            // methods inherit from.  If you don't have a base class, you can just use
            // whatever parent class you know your own API methods sit within.  
            // And if there is no parent class, then just get every time in the assembly
            var ass = System.Reflection.Assembly.GetAssembly(typeof(BaseController));

            // Get each class
            foreach (var controller in ass.GetTypes())
                if (controller.IsSubclassOf(typeof(BaseController))) ExtractMethods(controller);

        /// <summary>
        /// Finds the methods in this controller
        /// </summary>
        /// <param name="controller"></param>
        private void ExtractMethods(Type controller)
            foreach (var method in controller.GetMethods())
                // My API methods are decorated with a custom attribute, 
                // ApiMethodAttribute, so only show those ones
                var attrs = System.Attribute.GetCustomAttributes(method);

                // Check our attributes show we have an API method
                var isAPIMethod = false;
                foreach (System.Attribute attr in attrs)
                    if (attr is ApiMethodAttribute)
                        isAPIMethod = true;

                // Break if not an API method
                if (!isAPIMethod) continue;

                // Parse out properties
                var meth = new Method();
                meth.Name = controller.Name.Replace("Controller", "") + "/" + method.Name;

                // Quick hack to detect the XML segment we want - I know that 
                // all my API methods are in *Controller methods, so I can just restrict to this
                var memberName = "Controller." + method.Name;

                // Get the methods from our documentation
                var docInfo = (
                              from m in this.XmlDocumentation.Descendants("members").Descendants("member")
                              where m.Attribute("name").Value.Contains(memberName)
                              select new {
                                  Summary = m.Descendants("summary").First().Value,
                                  Params = m.Descendants("param")

                // Now copy the XML back into my method/parameter classes
                if (docInfo != null)
                    meth.Summary = docInfo.Summary;

                    // Add parameters
                    foreach (var param in docInfo.Params)
                        var p = new Parameter();
                        p.Name = param.Attribute("name").Value;
                        p.Description = param.Value;

Note that this won’t compile for you because it references a custom attribute, ApiMethodAttribute, and my base class, BaseController. However, you could delete the logic around these and the documentation should still generate.

Now it’s just a matter of calling the class. I use mine in an MVC ActionResult:

/// <summary>
/// Uses reflection to document our API methods
/// </summary>
/// <returns></returns>
public ActionResult APIDocumentation()
    var pathToDocs = HttpContext.Server.MapPath("~/bin/APIDocumentation.xml");
    var model = new ApiDocumentationGenerator(pathToDocs);
    return View("admin/apidocumentation", model);

And for clarity, I’ll include my View, so you can see how it’s used to render the results to the user:

@model Web.Code.ApiDocumentationGenerator
    ViewBag.Title = "API Documentation";

<h2>API Documentation</h2>

@foreach (var method in Model.Methods.OrderBy(x => x.Name))
    if (method.Parameters.Any())
             @foreach (var param in method.Parameters)
                 <li><strong>@param.Name </strong>@param.Description</li>

Hope that helps!


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Ben Liebert
Architect BlackBall Software
New Zealand New Zealand
No Biography provided

You may also be interested in...


Comments and Discussions

GeneralMy vote of 5 Pin
Bruno Tagliapietra28-Apr-14 0:06
memberBruno Tagliapietra28-Apr-14 0:06 
GeneralNo code download, and embedded snippets are unreadable Pin
John Brett24-Apr-14 3:27
memberJohn Brett24-Apr-14 3:27 
GeneralRe: No code download, and embedded snippets are unreadable Pin
MrChrisBarker24-Apr-14 22:21
memberMrChrisBarker24-Apr-14 22:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03-2016 | 2.8.180318.3 | Last Updated 24 Apr 2014
Article Copyright 2014 by Ben Liebert
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid