C# get class and method summary

/// <summary>
///Class Summary, Xml Comments Summary
/// </summary>
public class XmlCommentsSummary
{
/// <summary>
/// Print DateTime Now
/// </summary>
public void PrintTime()
{
Console.WriteLine($"Now is {DateTime.Now.ToString("yyyyMMddHHmmssffff")}");
}

/// <summary>
/// Print random guid
/// </summary>
public void PrintGuid()
{
Console.WriteLine($"Guid is {Guid.NewGuid().ToString()}");
}
}

 

1.via OOS Namotion.Reflection

using Namotion.Reflection;

 static void SummaryDemo()
        {
            Type type = typeof(XmlCommentsSummary);
            string summary = type.GetXmlDocsSummary();
            Console.WriteLine(summary);

            MethodInfo[] mis = type.GetMethods();
            if(mis!=null && mis.Any())
            {
                foreach(var mi in mis)
                {
                    string sum = mi.GetXmlDocsSummary();
                    if(!string.IsNullOrWhiteSpace(sum))
                    {
                        Console.WriteLine($"Method Name:{mi.Name},summary:{sum}");
                    }                    
                }
            }
        }

2.Copy stackoverflow solution from https://stackoverflow.com/questions/15602606/programmatically-get-summary-comments-at-runtime

/// <summary>
    /// Utility class to provide documentation for various types where available with the assembly
    /// </summary>
    public static class DocumenationExtensions
    {
        /// <summary>
        /// Provides the documentation comments for a specific method
        /// </summary>
        /// <param name="methodInfo">The MethodInfo (reflection data ) of the member to find documentation for</param>
        /// <returns>The XML fragment describing the method</returns>
        public static XmlElement GetDocumentation(this MethodInfo methodInfo)
        {
            // Calculate the parameter string as this is in the member name in the XML
            var parametersString = "";
            foreach (var parameterInfo in methodInfo.GetParameters())
            {
                if (parametersString.Length > 0)
                {
                    parametersString += ",";
                }
                parametersString += parameterInfo.ParameterType.FullName;
            }

            //AL: 15.04.2008 ==> BUG-FIX remove “()” if parametersString is empty
            if (parametersString.Length > 0)
            {
                return XmlFromName(methodInfo.DeclaringType, 'M', methodInfo.Name + "(" + parametersString + ")");
            }
            else
            {
                return XmlFromName(methodInfo.DeclaringType, 'M', methodInfo.Name);
            }
        }

        /// <summary>
        /// Provides the documentation comments for a specific member
        /// </summary>
        /// <param name="memberInfo">The MemberInfo (reflection data) or the member to find documentation for</param>
        /// <returns>The XML fragment describing the member</returns>
        public static XmlElement GetDocumentation(this MemberInfo memberInfo)
        {
            if (memberInfo != null)
            {
                // First character [0] of member type is prefix character in the name in the XML
                return XmlFromName(memberInfo.DeclaringType, memberInfo.MemberType.ToString()[0], memberInfo.Name);
            }
            return null;
        }
        /// <summary>
        /// Returns the Xml documenation summary comment for this member
        /// </summary>
        /// <param name="memberInfo"></param>
        /// <returns></returns>
        public static string GetSummary(this MemberInfo memberInfo)
        {
            if (memberInfo != null)
            {
                var element = memberInfo.GetDocumentation();
                var summaryElm = element?.SelectSingleNode("summary");
                if (summaryElm == null)
                {
                    return "";
                }
                return summaryElm.InnerText.Trim();
            }
            return null;
        }

        /// <summary>
        /// Provides the documentation comments for a specific type
        /// </summary>
        /// <param name="type">Type to find the documentation for</param>
        /// <returns>The XML fragment that describes the type</returns>
        public static XmlElement GetDocumentation(this Type type)
        {
            // Prefix in type names is T
            return XmlFromName(type, 'T', "");
        }

        /// <summary>
        /// Gets the summary portion of a type's documenation or returns an empty string if not available
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static string GetSummary(this Type type)
        {
            var element = type.GetDocumentation();
            var summaryElm = element?.SelectSingleNode("summary");
            if (summaryElm == null)
            {
                return "";
            }
            return summaryElm.InnerText.Trim();
        }

        /// <summary>
        /// Obtains the XML Element that describes a reflection element by searching the 
        /// members for a member that has a name that describes the element.
        /// </summary>
        /// <param name="type">The type or parent type, used to fetch the assembly</param>
        /// <param name="prefix">The prefix as seen in the name attribute in the documentation XML</param>
        /// <param name="name">Where relevant, the full name qualifier for the element</param>
        /// <returns>The member that has a name that describes the specified reflection element</returns>
        private static XmlElement XmlFromName(this Type type, char prefix, string name)
        {
            string fullName;
            if (string.IsNullOrEmpty(name))
            {
                fullName = prefix + ":" + type.FullName;
            }
            else
            {
                fullName = prefix + ":" + type.FullName + "." + name;
            }
            var xmlDoc = XmlFromAssembly(type.Assembly);
            if (xmlDoc != null)
            {
                var matchedElement = xmlDoc["doc"]["members"].SelectSingleNode("member[@name='" + fullName + "']") as XmlElement;
                return matchedElement;
            }
            return null;
        }

        /// <summary>
        /// A cache used to remember Xml documentation for assemblies
        /// </summary>
        private static readonly Dictionary<Assembly, XmlDocument> Cache = new Dictionary<Assembly, XmlDocument>();

        /// <summary>
        /// A cache used to store failure exceptions for assembly lookups
        /// </summary>
        private static readonly Dictionary<Assembly, Exception> FailCache = new Dictionary<Assembly, Exception>();

        /// <summary>
        /// Obtains the documentation file for the specified assembly
        /// </summary>
        /// <param name="assembly">The assembly to find the XML document for</param>
        /// <returns>The XML document</returns>
        /// <remarks>This version uses a cache to preserve the assemblies, so that 
        /// the XML file is not loaded and parsed on every single lookup</remarks>
        public static XmlDocument XmlFromAssembly(this Assembly assembly)
        {
            if (FailCache.ContainsKey(assembly))
            {
                return null;
            }
            try
            {
                if (!Cache.ContainsKey(assembly))
                {
                    // load the docuemnt into the cache
                    Cache[assembly] = XmlFromAssemblyNonCached(assembly);
                }
                return Cache[assembly];
            }
            catch (Exception exception)
            {
                FailCache[assembly] = exception;
                return null;
            }
        }

        /// <summary>
        /// Loads and parses the documentation file for the specified assembly
        /// </summary>
        /// <param name="assembly">The assembly to find the XML document for</param>
        /// <returns>The XML document</returns>
        private static XmlDocument XmlFromAssemblyNonCached(Assembly assembly)
        {
            var assemblyFilename = assembly.CodeBase;

            const string prefix = "file:///";

            if (assemblyFilename.StartsWith(prefix))
            {
                StreamReader streamReader;

                try
                {
                    streamReader = new StreamReader(Path.ChangeExtension(assemblyFilename.Substring(prefix.Length), ".xml"));
                }
                catch (FileNotFoundException exception)
                {
                    throw new Exception("XML documentation not present (make sure it is turned on in project properties when building)", exception);
                }

                var xmlDocument = new XmlDocument();
                xmlDocument.Load(streamReader);
                return xmlDocument;
            }
            else
            {
                throw new Exception("Could not ascertain assembly filename", null);
            }
        }
    }


static void GetXmlSummaryComments()
        {
            Type type = typeof(XmlCommentsSummary);
            string typeSummary = type.GetSummary();
            Console.WriteLine($"{typeSummary}");
            MethodInfo[] mis = type.GetMethods();
            if (mis != null && mis.Any())
            {
                foreach (var mi in mis)
                {
                    string methodSummary = type.GetMethod(mi.Name).GetSummary();
                    if(!string.IsNullOrWhiteSpace(methodSummary))
                    {
                        Console.WriteLine($"Method Name:{mi.Name},summary:{methodSummary}");
                    } 
                }
            } 
        }

 

posted @ 2020-05-07 12:04  FredGrit  阅读(1415)  评论(2编辑  收藏  举报