| 加入收藏| 设为首页| 联系我们

首页 站长学习 站长之家 源码下载 建站素材 书籍教程 常用工具
 您现在的位置: 动力中国 >> 网络编程 >> ASP.NET教程 >> 文章正文  
 [组图]扩展Kevin McFarlane的C#版DesignByContract Framework
 

扩展Kevin McFarlane的C#版DesignByContract Framework

http://www.domcn.org  文章来源:本站收藏  点击数:

  关键字:扩展Kevin McFarlane的C#版DesignByContract Framework

Kevin McFarlane的C#版DesignByContract Framework实现从02年在CodeProject发布至今,几乎成为C#开发中大多数朋友使用的事实标准。本文结合对该框架的使用经验,在Kevin的原始版本的基础上,使用Strategy Pattern对其进行进一步的扩展,对最常用的检查语义进行封装简化。本文改进的源码以Public Domain协议发布,也就是说,完全没有任何限制。

如果您愿意,不强制,使用该代码时,请保留该源码文件顶部的注释。

Kevin McFarlane的C#版DesignByContract Framework实现在CodeProject.com的原文地址:http://www.codeproject.com/csharp/designbycontract.asp

下载改进版本的DesignByContract源码及测试工程源码(测试工程为VS2005 VSTS测试工程格式):DesignByContract_Enhanced_Version.zip

使用简介

对于该框架的基本使用介绍,请参见上面Kevin McFarlane写在CodeProject.com的原文。

下面主要介绍扩展部分的使用方法。

启用Trace或Debug的Assertion

类似原始版本,默认情况下Check.Require()等方法失败会抛出PreconditionException等异常,可以在它的工程的Conditional compilation symbols中添加USE_TRACE_ASSERTION或USE_DEBUG_ASSERTION。这两个symbols分别表示用System.Diagnostics.Trace.Assert()或System.Diagnostics.Debug.Assert()提示检验失败消息,而不是默认的抛出异常。

当使用这两个symbols时,可以在使用代码的启动初始化代码(例如Global.asax的Application_Start)中通过类似下面的代码改变默认的错误提示或日志记录方式:

System.Diagnostics.Trace.Listeners.Clear();
System.Diagnostics.Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));

注1:对ASP.NET程序,请总是使用USE_DEBUG_ASSERTION。
注2:默认情况下,.NET 2.0程序工程的trace和debug在工程Debug编译模式下是默认启用的,Release编译模式下trace默认被启用,debug默认并不启用,不过,可以在工程的属性中手动修改这两个设置。

修改错误提示消息文本模版

原始版本中的默认错误提示是English的,而且直接hardcode,并且分散在源代码各个方法中,如果我们想改变错误提示类型就不是那么方便,在本改进版本中,所有的错误提示消息的文本模版我都提出来放到源文件的Check类定义最开头的#region Const Literals中,方便大家修改。如果您需要从外部资源文件中读取这些信息,您可以将#region Const Literals中的这些变量都改成private static readonly的,并在Check的static构造函数中从外部资源文件读取。

基于Strategy模式的Check逻辑封装和使用

在改进版本中最大的改进在于增加了一组Check Strategies。所有的Check Strategy都实现ICheckStrategy接口,并在Check类中定义了静态成员变量来方便访问他们的实例。

ICheckStrategy的定义如下:

1        public interface ICheckStrategy
2        {
3            bool Pass(object obj);
4            string GetFailingMessage(string objName);
5        }
Pass方法需要实现对obj的检查逻辑,返回true表示通过检查,GetFailingMessage方法用于返回错误提示消息。

本改进版本内置实现了如下的Check Strateies:

NotNull - 可用于检查任意对象是否为null
NotNullOrEmpty - 可用于检查string,Array或ICollection类型的对象非null且非空,Array和ICollection为空这里指其包含的元素个数为0
IsAssignableTo<TargetType> - 可用户检查指定对象是否可以被转换为TargetType类型的实例
GreaterThan<T>/LessThan<T>/GreaterThanOrEqual<T>/LessThanOrEqual<T> - 顾名思义,这一组Strategies可用于检查大于、小于等范围

这些类并不需要也不能(内置实现类的构造函数是private的,不能直接调用)显式实例化,只需要使用Check类的静态成员进行访问:

如:

Check.NotNull
Check.NotNullOrEmpty
Check.IsAssignableTo<TargetType>()
Check.GreaterThan<T>(T compareValue)
Check.LessThan<T>(T compareValue)
Check.GreaterThanOrEqual<T>(T compareValue)
Check.LessThanOrEqual<T>(T compareValue)

同时,本改进版本也为Check的Require,Ensure等方法增加了一个象下面这样的重载:

public static void Require(object obj, string objName, params ICheckStrategy[] strategies)

该重载的第一个参数为要检查的对象,第二个参数表述被检查对象的描述名称(不一定是变量或参数名,可以使更易于理解的描述名称),第三个参数是一组可变数量的ICheckStategy实例。

使用示例(更多使用示例可以参见本文源代码中的测试工程):

1        private static void RequireStrategy(TestClass obj, object objs, object objList)
2        {
3            Check.Require(obj, obj, Check.NotNull);
4            Check.Require(objs, objs, Check.NotNull, Check.IsAssignableTo<Array>(), Check.NotNullOrEmpty);
5            Check.Require(objList, objList, Check.NotNull, Check.IsAssignableTo<ICollection>(), Check.NotNullOrEmpty);
6        }
示例代码中的RequireStategy方法的被检查参数类型可以但不一定是强类型的。

对于最常用的NotNull检测,如Check.Require(obj, obj, Check.NotNull)中,Check.NotNull可以不指定,也就是说Check.Require(obj, obj)等价于显式指定Check.NotNull。

Check.Require()的这个重载的最后一组参数是一组Check Stategies,当指定多个时,他们的Pass方法会被依次调用,一旦遇到Pass返回false,则终止后续检查,提示信息只包含第一个Pass通不过的Stategy的错误提示。

以上示例代码中的第二、三个Require()方法的调用,相当于检查数组或集合对象的类型和是否非空(包含的元素数为0)。NotNullOrEmpty这个Strategy也可以用于对string类型的检查。对非string、Array或ICollection类型,他的Pass方法总是返回false的。

类似的,使用GreaterThan等Strategies的示例代码如下:

1        private static void CompareArguments(int x, int y, double z)
2        {
3            Check.Require(x, x, Check.GreaterThan<int>(0));
4            Check.Require(y, y, Check.LessThanOrEqual<int>(0));
5            Check.Require(z, z, Check.GreaterThanOrEqual<double>(0.1));
6        }
我们也可以用像Check.Require(x, x, Check.GreaterThan<int>(0), Check.LessThanOrEqual<int>(10))这样的语法检查x是否0<x<=10。

您可能要问使用Strategy这样的语法相比Check.Require(obj != null, obj could not be null.)这样的语法有何优势?

最大的优势在于,您不必对常用的检查类型一遍遍重复的指定错误的描述信息,如obj could not be null.这种描述信息,可以少打很多字母。而且,基于Strategy使得,对常用检查逻辑的封装扩展非常灵活便捷。我们可以方便的继承ICheckStrategy接口,扩展我们自己的查询逻辑。

前面说过了,在Check类的#region Const Literals中定义了所有的默认错误描述消息模版,我们可以根据需要修改默认的提示消息,当然,对大多数应用来说,使用默认的English提示消息也足够了。下面简单列举了在默认抛出异常工作模式下一些常见的Strategy检查失败后的错误消息:

Check.NotNull - Test method DesignByContract.UnitTests.TestPreconditionNull threw exception:  DesignByContract.PreconditionException: obj could not be null.

Check.NotNullOrEmpty - Test method DesignByContract.UnitTests.TestPreconditionStrategyCollectionEmpty threw exception:  DesignByContract.PreconditionException: objList could not be null or empty.

Check.IsAssignableTo<ICollection>() - Test method DesignByContract.UnitTests.TestPreconditionStrategyCollectionNotIsAssignableFrom threw exception:  DesignByContract.PreconditionException: objList is not assignable to System.Collections.ICollection.

Check.GreaterThanOrEqual<double>(0.1) - Test method DesignByContract.UnitTests.TestCompareDoubleGreaterThanOrEqual threw exception:  DesignByContract.PreconditionException: obj must be >= 0.1.


扩展Kevin McFarlane的C#版DesignByContract Framework
  • 上一篇文章:

  • 下一篇文章:
  •  热门文章
    普通文章 电子邮件改头换面 四公司畅谈未
    普通文章 PC病毒史上最声名狼藉的八大病
    普通文章 Rails系统中的AJAX开发技术简析
    普通文章 基于ASP.NET AJAX框架实现表单
    普通文章 开发ASP.NET AJAX客户端定制行
    普通文章 用JFreeChart对JSP报表进行增强
    普通文章 SQL Server 2005上的CLR和ADO.
    普通文章 SQL Server 2005的XML支持机制
    普通文章 Firefox中标签式浏览技巧大全
    普通文章 Tomcat中的Session和Cookie大揭
     
     推荐文章
    推荐文章 把Google地图嵌入网页 就是这么
    推荐文章 迅雷搜索候选资源出错的解决
    推荐文章 轻松去除迅雷里的各种广告和资
    推荐文章 突破限制 免费领养到QQ空间五级
    推荐文章 Rational统一过程RUP贴近中小软
    推荐文章 构建自己的轻量级XML DOM分析程
    推荐文章 WPS Office 2007技巧:妙用配置
    推荐文章 Excel 2007:求余数函数实用进阶
    推荐文章 浅谈ASP.NET的Postback
    推荐文章 软件开发中项目需求管理简述
     
     相关文章
    没有相关文章
    设为首页 | 加入收藏 | 广告合作 | 联系站长 | 版权申明 |
    动力中国为网友提供免费学习资料,可用资源,如果您认为我们的相关内容侵害到了您的权利请联系管理员
    Copyright © 2006-2008 domcn.org All Rights Reserved.