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的这篇文章继承本质论


BlogEngine中的Provider模式(上)

Post on by michaelyin

BlogEngine中的数据存储部分使用了Provider模式来支持多种数据存储方式,比如Sql server,XML等。只需要通过修改Web.Config文件中的响应配置节就可以按需求进行数据存储方式的改变。

<configSections> 
    <sectionGroup name="BlogEngine"> 
        <section name="blogProvider" requirePermission="false" type="BlogEngine.Core.Providers.BlogProviderSection, BlogEngine.Core" allowDefinition="MachineToApplication" restartOnExternalChanges="true"/> 
    </sectionGroup> 
</configSections>

首先在Web.Config中定义BlogEngine这个自定义节点,sectionGroup这个是存放section元素的容器,它不是必须要写的。section则是将配置节中的配置信息和配置处理程序提供关联。这里我们可以看到,它将blogProvider这个配置节和BlogProviderSection这个类提供了关联,name= “blogProvider”说明配置节为blogProvider

public class BlogProviderSection : ConfigurationSection
{
    /// <summary>
    /// A collection of registered providers.
    /// </summary>
    [ConfigurationProperty("providers")]
    public ProviderSettingsCollection Providers
    {
      get { return (ProviderSettingsCollection)base["providers"]; }
    }
    /// <summary>
    /// The name of the default ...

Random 学习笔记

Post on by michaelyin

这几天在学习算法,所以生成随机数组就不可避免了,以前只是知道Random 这个类是用来生成随机数的但是没怎么用过,这次正好趁这个机会好好了解一下,在园子里面看了下别人写的文章和代码,自己又在VS里面跑了几次,这里就把一些觉得useful的东东记下来。

Random是用来生成伪随机数的类,它根据生成对象时候的随机种子进行复杂的计算,然后生成伪随机数。如果我们在调用构造函数的时候没有指定随机种子,那么默认情况下它会采用系统的时间产生的值来做随机种子,这样的话那么我们在一次函数调用里面不同的Random对象有可能是采用相同的随机种子,那么有可能造成生成重复的随机数。关于随机种子的选取问题,等下会专门讲解。Random里面要用到比较多的方法就是obj.Next()这个方法,用于根据随机种子按照复杂的算法生成伪随机数,这个方法有多个重载的方法,可以限定需要生成的数字的最大值和最小值,基本上Random经常使用的就是这么几个东西。

下面来讲一下如何避免生成重复的随机种子,以此来避免产生一连串重复的随机数。其实关键点就在于生成随机数的随机种子必须不一样,一种方法就是采用Guid.NewGuid().GetHashCode()来当做随机种子,由于Guid重复的可能性非常小,而且Hash算法不同的输入产生的结果也是不同的,所以可以很好的解决随机种子相同的问题。还有一种方法就是采用

long tick = DateTime.Now.Ticks; 
Random ran = new Random((int)(tick & 0xffffffffL) | (int) (tick >> 32)); 

这个方法来达到效果

园子里面有的朋友是用算法来完成生成不重复随机数的,这样可以完全避免重复数据的发生。

public static int[] CreateInstanceType2()
{
    int[] result = new int[10];
    int tmp = -1;
    Random random ...

算法学习之插入排序

Post on by michaelyin

最近开始学习算法方面的东西,用的资料是算法导论,在这里也顺便把学习过程中的心得,体会等,在这里做个总结,并给出自己用c#实现的代码。

说个简单点的例子,就拿算法导论一书中的Poker的例子来说吧。刚开始我们的手上有一张牌,而这张牌肯定是没有排序的大小顺序问题的,桌子上放的牌就是剩下的都没有排序的那些牌,我们将牌从桌子上拿起来,然后从右往左边看,看到一个比我们刚摸上来的牌小的牌后,把手上这个牌右边的牌都朝右边挪动一个位子,然后把刚摸起来的这张牌插入到空出来的这个位置中去。

下面给出实现的代码

/// <summary>
/// 插入排序
/// </summary>
/// <param name="arrayToSort">需要排序的数组</param>
public static void InsertionSort(int[] arrayToSort)
{
    //从第二个元素开始
    for (int j = 1; j < arrayToSort.Length; j++)
    {
        int key = arrayToSort[j];
        int i = j - 1;
        //注意防止索引越界
        while (i > -1 && arrayToSort[i] > key)
        {
            arrayToSort[i + 1] = arrayToSort[i];
            i--;
        }
        arrayToSort[i + 1] = key ...

母版页中的js和css文件引用路径的问题

Post on by michaelyin

今天在做项目的时候发现了母版页中引用css文件和js文件路径在内容页中发生路径错误。

先来说说问题发生的情况吧,比如我在一个母版页中引用了一个js文件和一个css样式表文件,路径是使用的相对路径,代码是这样子的

<link href="../css/dtree.css" rel="stylesheet" type="text/css" />
<script src="../js/dtree.js" type="text/javascript"></script>

母版页我放在项目文件MasterPage文件夹中,脚本文件和css文件我分别放在相应的文件夹中,在Design模式中这也是可见的,然后我加入内容页,内容页假设我放在网站根目录下面,然后放入内容,进入后台进行编程,基本上完成以后想看看效果,就F5进行了调试,不过缺发现js没有起作用,在IE下查看源文件,发现引用处的css和js的路径发生了变化,如下所示

<link href="css/dtree.css" rel="stylesheet" type="text/css" />
<script src="../js/dtree.js" type="text/javascript"></script>

从这里可以看到 ...