上文有说到创建自定义活动的上半部分,所以现在把下半部分补齐。
写之前呢,有点感想,貌似m$的lab实在太过细致,细到什么程度可以看上篇中相关链接。另外,对于WF中的一些概念,由于我也是刚接触,但在看完lab02和lab03之后(现在看lab04ing),发现在WF中很强调一个概念:继承+重写(override),无论是Activity这个概念本身,还是一些相关的Profile以及Scheduler等等,另外,这其中也包含了相关的设计模式(Design Pattern),如最常见的singleton,以及Strategy等等,在WF架构内部大量应用了反射。所以在3.0真正席卷而来之时,更应该学好这些基础的东东。
废话少说,切入正题。
第三课 给邮件参数添加验证器(Adding Validation to Check E-Mail Parameters)
Task1 - 添加一个邮件验证代码活动(Activity)//正所谓万物皆活动,所以Code这东西也可看作活动
活动验证器(Activity Validator)是活动组件模型(Activity Component Model)的一部分,它主要关注下面这些//post一开篇就提到过,WF中很强调继承与重写,或许这也是作为一个Lib设计所必需关注的要点?
- 设计器 该组件定义了活动在设计器中的可视部分,以及自定义的活动设计部分。
- 代码产生器 针对某个活动的代码生成的一个扩展,例如说InvokeWebService,就是这样一个东西//这个feature也就是说,在活动中有些外挂的代码生成工具,例如可以直接生成与WebService交互的代码
- 验证器 该组件会在设计时和运行时强制验证某属性是否合法(当然也是在自动更新时才起作用)
- 工具栏选项 定义活动在工具箱的自定义行为
- 执行()这是代表活动执行的一个无状态组件 //一个活动得以执行就靠override Execute方法了,下文中可以看到这方面的demo
- 序列化 定义自定义的序列化行为
- 部署 将活动部署到宿主环境中会用到它
OK,现在来看代码
在SendMailActivityLibrary 项目中添加新文件,选择Code File,取名为ParametersValidator.cs//从名字上也可以看出是要继承Validator的行为,也就是前文一再强调的继承与override
文件建好之后,让它继承自ActivityValidator,值得注意的是,ActivityValidator既有设计时也有运行时的验证逻辑,以确保一个活动是正确配置的。一般情况下,有两类这样的“验证器”:ActivityValidator和CompositeActivityValidator,具体选择哪个取决于我们选择的Activity的类型(是basic的还是Composite的,上篇post有提到过,还记得吗?)
下面,我们先override这样一个方法ValidateProperties (名字取得怪怪的),该方法用于验证一个活动属性的编译期语义。
代码如下
public override ValidationErrorCollection ValidateProperties(ValidationManager manager, object obj) { ValidationErrorCollection validationErrors = new ValidationErrorCollection(base.ValidateProperties(manager, obj)); SendMailActivity sendMailActivityToBeValidated = obj as SendMailActivity; if (sendMailActivityToBeValidated == null) { throw new InvalidOperationException("Parameter obj is not of type SendMailActivity"); } if (!IsValidEmailAddress(sendMailActivityToBeValidated.To)) { ValidationError CustomActivityValidationError = new ValidationError(String.Format("\'{0}\' is an Invalid destination e-mail address", sendMailActivityToBeValidated.To), 1); validationErrors.Add(CustomActivityValidationError); } if (!IsValidEmailAddress(sendMailActivityToBeValidated.From)) { ValidationError CustomActivityValidationError = new ValidationError(String.Format("\'{0}\' is an Invalid source e-mail address", sendMailActivityToBeValidated.From), 1); validationErrors.Add(CustomActivityValidationError); } return validationErrors; }
另外,还有一个IsValidAddress方法,具体内容也就是用正则匹配email表示字符串,这里就忽略了。
添加了这样一个验证器类之后,当然还需要让它工作起来,也就是要给它指定一个验证对象,当然也就是一个活动了:SendMailActivity,怎样添加验证对象?象这样:
[ActivityValidator(typeof(ParametersValidator))]
在SendMailActivity类名之前添加这样一个Attribute就OK了。
Task2 验证我们的验证器 :)
打开SendMailActivity的设计视图,其属性框的from属性添入一个非法的email地址,就可以看到该活动上出现一个红色感叹号,Wow,说明我们的验证器正常工作了!
第四课 添加活动设计器//实际上就是GDI+重写OnPaint方法
同样,我们需要像刚才那样添加一个CodeFile,取名为SendMailDesigner.cs,让其继承自ActivityDesigner,至于ActivityDesigner有哪些虚方法,我们需要从msdn中获取。该课中需要重写其Initialize,OnPaint,OnLayoutSize三个方法。
在Intialize方法中,主要是维护一个基类Activity对象的引用,同时初始化SendMailActivity活动。
在OnPaint方法中,当然主要关注的就是怎样来画这个布局了,这里就不列代码了,可自行参考我上篇post中相关链接(如果GDI+足够熟悉的话,也可以自己搞定)。
最后的图形象下面这个样子:
Lab02完,请继续关注Lab03