• 从写组件说Xml——改良(六)


    1.提出问题

        前面五篇说了如何实现,但是如果xml配置错了怎么办哪?

        首先,利用Xsd,已经可以保证大部分xml的类型不会出错,但是,之前把Expression设计为弱类型的,也就意味着Expression不对其返回的类型负责,这是第一个在xml运行时存在的不稳定因素。

        第二,变量本身也有不安全因素,首先变量名本身就非常容易出现书写错误,其次,变量名本身也是弱类型的,不到运行时,根本不知道里面到底放的是什么。

        第三,参数(Parameter)。参数是在IGeneratorEngine的Generate方法输入的,因此,这里Xml配置中的参数是依赖于c#的输入的,而这个也是必须到运行时才能知道的。

        第四,CliFunction。这个PInvoke是为Xml调用.net方法而设计的,那么自然也就会有各种不稳定因素会出现。

        第五,实现本身的缺陷导致的问题。

    2.改良日志

        要排除以上运行时问题,最简单的方法就是记录日志。说到日志,是不是马上就想到:

    • Log4Net
    • Enterprise Library - Logging Application Block

        没错,这是两个用的最多的日志工具,但是,它们也是通用的日志工具,并不适合记录Xml的场合(至少,没法帮助我们直接定为到Xml的哪一行出的错)。

        所以,需要把日志服务包装一下:

    image

        现在只需要在实现TraceErrorCore的时候多添加一个Xml的调用堆栈即可。既然有调用堆栈,那就先要定义:

    image

        然后再定义调用堆栈:

    image

        然后再重写ToString方法:

    image

        然后准备一套关于Xml调用堆栈的扩展方法:

    image

        剩下来的就是让那些实现类额外实现一个IXmlFunction,例如:

    image

        这样就可以让每一个结构被调用时,把调用信息写入调用堆栈,并且可以在GetAdditionalInformation添加其它相关的参数信息。

        现在再回到TraceService,可以进一步把Core方法实现了(为了避免牵涉到具体的日志工具,就用.net自带的Trace来记录):

    image

        如果context为空,那就意味着当前不在Xml配置相关的运行状态,否则就记录相关的Xml调用堆栈。

        最后,把所有需要记录日志的地方替换成使用TraceService。现在Xml调用堆栈已经都准备好了。

    3.进一步改良日志

        前一节已经可以把日志定位到行为了,但是,这样依然不能知道到底是Xml的哪一行哪一列出了错。当然反序列化本身无法提供这样的信息。

        这里,先引入一个接口:IXmlLineInfo

        用Reflector来看一下哪些类实现了这个接口:

    image 

    3.1 Linq to Xml

        首先是Linq to Xml的XObject实现了这个接口,因此先大概写一个XLinq的Loader:

    image

        因为IXmlLineInfo接口是只读的,因此,需要再定义一个写入这些行信息的接口:

    image

        然后让Slide实现这个接口:

    image

        别忘了给新添加的公共属性添加XmlIgnore特性,否则会影响Xml序列化的行为。

        再次回到XLinqLoader,现在需要额外添加IXmlLineInfo的信息:

    image

        如此就可以完成了一个使用Linq to Xml的Loader。

    3.2 XPathDocument

        再次看一下实现IXmlLineInfo的实现类:

    image

        这次关注一下选中的这个类,当然这个类型不是公开的,不过可以用Reflector分析一下:

    image

        该分析指出,这个类是由XPathDocument的CreateNavigator方法来创建实例的,进一步用Reflector查看这个方法:

    image

        也就是说,CreateNavigator返回的就是这个类型的一个实例。

        那么再写一个利用XPathDocument的Loader:

    image

        (XPathDocument的Navigator是只读的,所有修改内容的方法都将抛出NotSupportedException

    3.3 其它

        除了上面介绍的两个方法,也可以用XmlReader方式读取,用XmlReader.Create方法创建的一个XmlReader的实例,然后强转成IXmlLineInfo就可以了。

    4.改良日志提供LineInfo

        第二节的日志已经提供了Xml的相关信息,而在第三节又提供了LineInfo,那么在这一节,就把LineInfo写到日志里面,再次改造一下XmlCallStack的ToString方法:

    image

        这样Xml的日志已经基本完成了。


    上一篇:从写组件说Xml——实现(五)


  • 相关阅读:
    机器学习:逻辑回归(基础理解)
    机器学习:模型泛化(L1、L2 和弹性网络)
    机器学习:模型泛化(LASSO 回归)
    机器学习:模型泛化(岭回归:Ridge Regression)
    Numpy:np.random 的使用
    ASP.NET MVC 视图层-生成链接相关(Html.ActionLink,Url.Action)
    eval实例
    <a>实现按钮的javascript+jquery编程实例
    SQL Server之XML PATH()
    分页数算法
  • 原文地址:https://www.cnblogs.com/vwxyzh/p/1578466.html
Copyright © 2020-2023  润新知