BlogEngine中的BlogSettings

Post on by michaelyin

BlogEngine中的BlogSettings这个类是用来提供整个系统的设置参数的,参数的读取采用的是反射获取属性名称,然后遍历进行赋值,个人觉得这段代码值得学习

private void Load()
{
    Type settingsType = this.GetType();

    //------------------------------------------------------------
    //  Enumerate through individual settings nodes
    //------------------------------------------------------------
    System.Collections.Specialized.StringDictionary dic = Providers.BlogService.LoadSettings();

    foreach (string key in dic.Keys)
    {
        //------------------------------------------------------------
        //  Extract the setting's name/value pair
        //------------------------------------------------------------
        string name = key;
        string value = dic[key];

        //------------------------------------------------------------
        //  Enumerate through public properties of this instance
        //------------------------------------------------------------
        foreach (PropertyInfo propertyInformation in settingsType.GetProperties())
        {
            //------------------------------------------------------------
            //  Determine if configured setting matches current setting based on name
            //------------------------------------------------------------
            if (propertyInformation.Name.Equals ...

MSchart与Zedgraph使用初探及比较

Post on by michaelyin

最近项目中的统计图表功能需要重新进行下调整,所以这两天花时间学习了下关于统计图表方面的东西。

统计图表的实现方式常用的有Flash方式和图片方式,我这两天主要是把MsChart和Zedgraph研究了一下,简单说下MSchart,这个图表解决方案是微软官方提供的图表解决方案,使用的时候需要.Net3.5 Sp1(在一篇文章的评论中看到有人说.net2.0中也能用,只是需要把需要用到的dll手动加到bin文件夹中去),然后需要安装一个文件,也就是把几个需要用到的dll放到机器里面去。然后有一个安装文件在你的VS中安装控件,这样你就可以通过拖拉的方式直接在项目中使用mschart,需要注意的是在拖拉控件的同时它会修改你的Web.Config文件,当然了,如果你不想在toolbox中加入控件,也可以不安装VS控件,直接在项目中编码的方式来使用就行了,在重复一遍,Mschart.exe那个是必须要装的。如果你想进一步了解Mschart的使用,微软网站上有一个关于这个控件使用的样例项目,里面关于这个控件的例子已经写的很全面了。

相比于Zedgraph,Mschart对前台声明式的编程支持的更好,很多东西都可以通过在前台声明来控制。Chart这个标记代表了整个控件,Legends这个标记是整个Chart的说明,Series代表Chart中的一连串数据,比如折线图中的一连串数据点就是一个Series,你可以向里面插入Points这个对象,来完成数据的绑定。ChartArea是作图区域,一个Chart控件中可以有几个ChartArea,比如如果有两个ChartArea的话生成的图就会有两个图表,AxisY和AxisX下提供了基本的控制样式的属性.

Mschart支持多种数据源的绑定,而且和.Net本身的结合的夜更紧密,比如

Chart1.Series["Series1"].Points.DataBindXY(myReader, "TimeDetail", myReader, "Temperature");

这句代码就是直接通过一个DataReader绑定到Chart控件中,你只需要指定DataReader和字段值,然后数据就会自己绑定到mschart上去,坐标轴的间距都可以自己根据具体的数据生成,你也可以通过编程手动的来制定左边的最小,最大值,以及坐标的间距,这些在我前面提到的样例代码中都有,有兴趣的可以自己去看。

Mschart使用过程中发现的唯一有点点不爽的就是它的中间的线默认是画上去的,也就是那个Gridline,如果你的背景是纯色的还好,将颜色设置成一样就没事了,如果是渐变的背景 ...


Subsonic查询中奇怪的数据丢失问题

Post on by michaelyin

昨天在项目中遇到了一个很奇怪的问题,用Subsonic查询出来的对象中部分字段值出现了丢失,比如我写这样一个查询语句

ViewIceCalculate objViewIce = new Select().Top("1").From<ViewIceCalculate>().ExecuteSingle<ViewIceCalculate>();

后面的查询跟Sql语句差不多的,返回一个对象,但是从程序Debug中来看的话,有些属性并没有取到值,这个有点奇怪的现象引起了我的兴趣,在网上找了一下,找到了对应的源码,将SubSonic Project加载到我实验的Console的Project中去,查询中所调用的东西都在里面。

然后再Subsonic中去看了一下,由于是从new Select开始的查询,所以先看看Select这个类把,发现Select这个类继承自SqlQuery,又跑到SqlQuery这个类中一窥究竟。在SqlQuery我没有看到Top,不过发现了一个名叫From的方法,看来有戏啊,继续发现之旅。。。看看这里里面有没有ExecuteSingle,结果还真有,一路找寻,找到了一个叫BuildSqlStatement的方法,看样子Sql语句的拼凑是在这里完成的,果断设断点,然后启动调试,到这里将生成的Sql语句贴到SQl中运行,数据是可以全部查出来的,那么问题就不出在这里了。。

数据查寻出来后返回的是一个IDataReader的接口,ExecuteSingle中还有另外一个叫做BuildTypedResult的方法,在代码中找到方法的代码,然后设了断点,然后。。。我知道悲剧为什么发生了。。。。

先上代码吧。

PropertyInfo[] cachedProps = new PropertyInfo[rdr.FieldCount];
                for (int i = 0; i < rdr.FieldCount; i++)
                    cachedProps ...

算法学习之合并排序

Post on by michaelyin

在我的前面的一篇Post中我讲了排序算法中很基本的插入排序,插入排序实现的算法思想是增量方法,即排好子数组之后,加入一个新的元素,然后再进行一个排序操作,保证重新生成按序排列的数组。

这篇Post我将简单的讲讲排序算法另外一种算法,合并算法,合并算法采用分治法的思路,即问题划分成n个规模较小而结构和原来问题相似的子问题,递归解决这些子问题,然后合并结果,最终得到原来问题的解。

合并算法主要分为三个部分,第一个部分是分解,将运来的问题分解成两个包含n/2个元素的数组的排序的问题,然后分别递归调用函数解决这两个数组的排序问题,最后一步,就是将已经排好序的数组重新进行组合,使其成为按序排列的数组。

这三步中代码量较多的就是合并的代码了,合并的问题其实我们也可以把它想象成把两堆已经按从小到大的顺序排好的扑克牌排成一堆扑克牌的问题,每次比较最上面的那个牌,小的就拿走放到输出堆中,重复这个比较过程直到某一堆牌为空,然后把另外一堆牌直接放到输出堆中这个比较过程就结束了,想清楚了了这个过程的话理解代码就不难了。

下面我将合并的代码贴出来

public static void Merge(int[] rawArray, int firstIndex, int middleIndex, int lastIndex)
{
    //把middle指向的元素划分到前面的一个数组去
    int firstArrayCount = middleIndex - firstIndex + 1;
    int secondArrayCount = lastIndex - middleIndex;

    int[] firstArray = new int[firstArrayCount];
    int[] secondArray = new int[secondArrayCount];

    //将原来数组的元素分别复制到两个分开的数组当中去
     for (int i = 0; i < firstArrayCount ...

BlogEngine中的Provider模式(下)

Post on by michaelyin

前面一篇Post主要专注于读取Web.Config中的配置的过程,这一篇将从面向对象的角度来阐述Provider的实现细节。

BlogEngine中其实很多处用到了Provider模式,而我希望就数据存储这部分把Provider给大家讲清楚,因为其他的地方和数据存储差不多,实现的方式大同小异。

BlogEngine中的BlogProvider是一个继承自ProviderBase的抽象类,在ProviderBase基础上加入了整个系统所有需要的方法签名,这个地方需要注意的是它并没有提供方法的具体实现的代码。XmlBlogProvider和DbBlogProvider都继承了BlogProvider,并且提供了具体的关于XML和数据库的实现方法的具体的代码。好了,现在让我们回头看BlogService这个类,整个系统的数据操作时这样的,逻辑代码调用BlogService中相应的方法,然后BlogService调用LoadProviders读取配置(如果已经读取就不用再次读取),然后操作已经经过实例化的BlogProvider的实例。

在这里笔者需要提醒的是抽象类其实是不能直接通过new关键字实例化的,通过不同的派生类的类型转换生成的抽象类虽然拥有一样名称的方法,但是具体的实现逻辑却并不是一样的,这其实就是一种面向抽象编程。这样做有什么好处呢?我们可以将针对不同数据存储方式的操作写到不同的继承自BlogProvider类的派生类中,然后在Web.Config中进行配置,程序中调用BlogProvider的方法进行逻辑方面的处理,而对于具体的数据存储的细节则不用关注太多。

对于派生类转换成基类后方法的调用细节不是很清楚的朋友可以看看Anytao的这篇文章继承本质论