1分钟生成Net对象的注释

      我们在开发过程中,肯定会有几个项目作为基础项目,存放一些比较常用的类和方法,供其他项目使用.一般来说,方法实现以后,就不想再去管它了,以致于新加入的某个伙计问这个项目里的方法有没注释或说明啊,一般的答案都是木有.之后的事情,大家就都知道了,不再描述了.

      其实生成项目里类或接口的注释,方法有很多,前几天还在园子里看到一篇使用Sandcastle软件生成DLL文件的CHM帮助文档,我目前也是使用这个软件生成API文档,地址没有找到.感兴趣的朋友可以去搜索下,本篇重点不是讲解这个软件如何使用.

      下面说一下业务场景,根据客户的业务需求,需要在NET程序里,展示某个类库中类的属性或方法列表供客户查看,如图-1所示

图-1

      使用反射方式,可以非常简单的生成如上图所示的结构,如果就这样拿过去给客户看的话,客户估计直接啥眼了,这些是什么东东呢?接着,经过你长时间耐心的教导和解释这些方法如何使用,最后终于功夫不负有心人啊,客户说:这个需求先不做了….额,不知道你是该高兴还是该悲催呢?

      OK,业务场景有了,我们就要找到方法解决它?起初,我采用的方法是通过Net的Attribute自定义属性来实现的.简单说下思路,就是创建如图-2所示的这些类,并且这些类均继承自Attribute类

图-2

      目前,这些类中,均定义了两个属性,DisplayText和Descrip,即各对象的中文显示名称和描述性文字,如图-3所示.这样我们就可以在反射获取类或方法的过程中,获取它的自定义属性信息,使用这种方式,解决了我们的大部分问题,可以说是基本可以实现的.不过,它需要对DLL文件中的每个类或方法加上我们刚刚创建好的自定义属性类,工作量也确实不小.而且,在描述方法的参数信息时,由于参数个数不确定性,导致自定义属性编辑比较麻烦.最终,这个方法Over掉,没有被采纳.

图-3

      前几天忽然想起,我们可以将DLL中的类或方法的注释,直接生成XML文件,即在生成DLL的配置项中,勾选XML documention file这个选项即可,它就会生成这个DLL文件的XML注释文件.如图-4所示

图-4

      我们现在来看看这个XML文件的格式,如图-5所示

图-5

      解析这个XML文件,对于我们来说,简直是小儿科了,而且我们需要做的事情,就是补齐每个类或方法的注释信息,而不必额外再使用自定义属性来记录注释信息了.如果你之前有比较好的习惯,类或方法都有注释的话,那么恭喜你.你的任务已经完成了.解析方法如图-6所示,在我提供的文件中是完整的,大家可以直接下载.

图-6

      看看我们解析的效果吧,如图-7所示.得到下面的数据后,在反射过程中,就可以在这里查找了,包括类名称,方法名称,还包括方法所需的参数名称,这里应有尽有啊.

代码片段

        /// <summary>
        /// 获取DLL文件类对象注释信息
        /// </summary>
        /// <param name="xmlFileName"></param>
        /// <returns></returns>
        public static DataTable GetTableMemberComments(string xmlFileName)
        {
            DataTable tableComments = null;

            //参数检测
            if (string.IsNullOrEmpty(xmlFileName)) return tableComments;

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlFileName);
            
            int i = 0;
            tableComments = new DataTable();
            tableComments.Columns.Add("Name", typeof(string));
            tableComments.Columns.Add("Comments", typeof(string));

            XmlNode xnMembers = xmlDoc.ChildNodes[1].ChildNodes[1];
            foreach (XmlNode xnMember in xnMembers.ChildNodes)
            {
                //获取方法名称,去掉前缀,获取"("之前的字符串
                string tempName = xnMember.Attributes["name"].Value.Trim();
                string memberName = tempName.Substring(2, tempName.Length - 2);
                string memberComments = xnMember.ChildNodes[0].InnerText.Trim();
                tableComments.Rows.Add(new object[] { memberName, memberComments });

                //获取方法参数,注:最后一个结点可能是返回值,需特殊处理
                int count = xnMember.ChildNodes.Count;
                if (count >= 2)
                {
                    string parameterName = string.Empty;
                    string parameterComments = string.Empty;

                    for (int j = 1; j < count - 1; j++)
                    {
                        parameterName = xnMember.ChildNodes[j].Attributes["name"].Value;
                        parameterComments = xnMember.ChildNodes[j].InnerText;

                        tableComments.Rows.Add(new object[] { memberName + "." + parameterName, parameterComments });
                    }

                    //处理最后一个结点
                    XmlNode xnLast = xnMember.ChildNodes[count - 1];

                    //根据结点名称判断
                    string xmlName = xnLast.Name.Trim().ToLower();
                    parameterComments = xnLast.InnerText;
                    if (xmlName == "returns")
                    {
                        parameterName = "Returns";
                    }
                    else
                    {
                        parameterName = xnLast.Attributes["name"].Value;
                    }

                    tableComments.Rows.Add(new object[] { memberName + "." + parameterName, parameterComments });
                }
                i++;
            }

            return tableComments;
        }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏分布式系统和大数据处理

C#网络编程(订立协议和发送文件) - Part.4

前面两篇文章所使用的范例都是传输字符串,有的时候我们可能会想在服务端和客户端之间传递文件。比如,考虑这样一种情况,假如客户端显示了一个菜单,当我们输入S1、S2...

11510
来自专栏分布式系统和大数据处理

基于业务对象(列表)的筛选

可能大家对SQL语句太过熟悉了,也可能虽然已经从Asp过度到了Asp.Net时代,但是Asp的观念没有发生太大变化。结果就是我们将应用程序大部分的逻辑都交给了数...

12150
来自专栏葡萄城控件技术团队

七天学会ASP.NET MVC(七)——创建单页应用

系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 ...

47560
来自专栏一个爱瞎折腾的程序猿

winform复制文件到指定目录

32610
来自专栏哲学驱动设计

asp.net MVC 应用程序的生命周期

  首先我们知道http是一种无状态的请求,他的生命周期就是从客户端浏览器发出请求开始,到得到响应结束。那么MVC应用程序从发出请求到获得响应,都做了些什么呢?

12730
来自专栏葡萄城控件技术团队

ASP.NET MVC 5 - 给数据模型添加校验器

在本节中将会给Movie模型添加验证逻辑。并且确保这些验证规则在用户创建或编辑电影时被执行。 拒绝重复 DRY ASP.NET MVC 的核心设计信条之一是DR...

22970
来自专栏Seebug漏洞平台

Exim Off-by-one(CVE-2018-6789)漏洞复现分析

前段时间meh又挖了一个Exim的RCE漏洞[1],而且这次RCE的漏洞的约束更少了,就算开启了PIE仍然能被利用。虽然去年我研究过Exim,但是时间过去这么久...

57470
来自专栏偏前端工程师的驿站

线程间通讯:WaitHandler使用实例及分析

实例效果: ? 1.点击“启动线程”会启动一个线程t每隔2秒在listbox上插入一条新记录。 2.点击“关闭线程”会停止线程t,但不是马上停止而是等待线程t当...

21450
来自专栏Objective-C

Swift-MVVM 简单演练(二)

42540
来自专栏哲学驱动设计

asp.net MVC 应用程序的生命周期

  首先我们知道http是一种无状态的请求,他的生命周期就是从客户端浏览器发出请求开始,到得到响应结束。那么MVC应用程序从发出请求到获得响应,都做了些什么呢?

12810

扫码关注云+社区

领取腾讯云代金券