WF4.0 Beta1中的規(guī)則引擎變化
在WF3.x時代我們可以使用聲明性的條件和代碼方式的條件,也可以使用支持正向鏈接的RuleSet。當然我們還可以使用基于CodeDOM的API來用代碼的方式聲明。
在微軟剛剛發(fā)布的WF4.0 Beta1中我們已經(jīng)看不到這些了,WF4.0提供了統(tǒng)一的完全聲明式的表達式(Expression)?,F(xiàn)在的版本只支持使用VB來構建表達式(Expression),但是在設計上是可以支持任何語言的,微軟也會在未來的版本中提供對其他語言的支持。
WF4.0中表達式是ValueExpression類型的,我們在VS中構造表達式的窗口是ExpressionTextBox類的實例,它也是可以再外部重新宿主的,只不過只有和VS結合的時候才有智能感知和顏色的支持。在表達式中我們可以引用工作流中的變量和參數(shù)。這些信息都會被序列化到XAML中。提供了表達式(Expression)并不是就不要原來的方式,微軟在開發(fā)WF4.0一個很重要的部分就是對WF3.x全面兼容。在WF4.0中提供了一個Interop活動可以幫助我們很好的完成現(xiàn)有WF3.x程序的遷移,我們只需要簡單的設置它的Body Type屬性即可,我們可以將WF4.0中的變量和參數(shù)綁定到WF3.x中的依賴屬性上,如下圖:
   
在WF4.0 beta1中沒有提供對正向鏈接的RuleSet功能,官方已經(jīng)聲明會在將來的版本中加大這部分的投入?,F(xiàn)在如果我們要想在WF4.0 Beta1使用類似的功能我們可以開發(fā)一個自定義活動來完成,下面的例子來源于WF Samples中,首先是活動的代碼部分:
- namespace Microsoft.Samples.Rules
 - {
 - using System;
 - using System.Activities;
 - using System.ComponentModel;
 - using System.Workflow.Activities.Rules;
 - using System.Workflow.ComponentModel.Compiler;
 - [Designer(typeof(Microsoft.Samples.Rules.PolicyDesigner))]
 - public sealed class Policy40Activity : NativeActivity
 - {
 - public RuleSet RuleSet { get; set; }
 - [IsRequired]
 - public InOutArgument TargetObject { get; set; }
 - public OutArgument<ValidationErrorCollection> ValidationErrors { get; set; }
 - protected override void OnOpen(DeclaredEnvironment environment)
 - {
 - if (this.RuleSet == null)
 - {
 - throw new System.ArgumentNullException("RuleSet property can't be null");
 - }
 - }
 - protected override void Execute(ActivityExecutionContext context)
 - {
 - // validate before running
 - Type targetType = this.TargetObject.Get(context).GetType();
 - RuleValidation validation = new RuleValidation(targetType, null);
 - if (!this.RuleSet.Validate(validation))
 - {
 - // set the validation error out argument
 - this.ValidationErrors.Set(context, validation.Errors);
 - // throw a validation exception
 - throw new ValidationException(string.Format("The ruleset is not valid. {0} validation errors found (check the ValidationErrors property for more information).", validation.Errors.Count));
 - }
 - // execute the ruleset
 - object evaluatedTarget = this.TargetObject.Get(context);
 - RuleEngine engine = new RuleEngine(this.RuleSet, validation);
 - engine.Execute(evaluatedTarget);
 - // update the target object
 - this.TargetObject.Set(context, evaluatedTarget);
 - }
 - }
 - }
 
下面是活動的設計器部分,在WF4.0中提供了對活動設計器的可視化支持:
- <sad:WorkflowElementDesigner x:Class="Microsoft.Samples.Rules.PolicyDesigner"
 - xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 - xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 - xmlns:sad="clr-namespace:System.Activities.Design;assembly=System.Activities.Design"
 - xmlns:sadv="clr-namespace:System.Activities.Design.View;assembly=System.Activities.Design">
 - <sad:WorkflowElementDesigner.Resources>
 - <sadv:ArgumentToExpressionConverter x:Uid="sadv:ArgumentToExpressionConverter_1" x:Key="argumentToExpressionConverter" />
 - </sad:WorkflowElementDesigner.Resources>
 - <Grid>
 - <Grid.RowDefinitions>
 - <RowDefinition x:Uid="RowDefinition_1" />
 - <RowDefinition x:Uid="RowDefinition_2" />
 - </Grid.RowDefinitions>
 - <Grid.ColumnDefinitions>
 - <ColumnDefinition x:Uid="ColumnDefinition_1" Width="70*" />
 - <ColumnDefinition x:Uid="ColumnDefinition_2" Width="196*" />
 - </Grid.ColumnDefinitions>
 - <Label Content="Target Object" Name="label1" Margin="0,5,0,7"/>
 - <sadv:ExpressionTextBox
 - x:Uid="ExpressionTextBox_1"
 - Grid.Row="0" Grid.Column="1"
 - AutomationProperties.AutomationId="TargetObject"
 - Width="190" Margin="9,7,9,7" MaxLines="1"
 - VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
 - Expression="{Binding Path=ModelItem.TargetObject, Mode=TwoWay, Converter={StaticResource argumentToExpressionConverter}, ConverterParameter=InOut}"
 - UseLocationExpression="True"
 - OwnerActivity="{Binding Path=ModelItem, Mode=TwoWay}" />
 - <Button Content="Edit RuleSet" Name="button1" Width="190" Margin="9,9,9,9" Click="button1_Click" Grid.Row="1" Grid.Column="1" />
 - </Grid>
 - </sad:WorkflowElementDesigner>
 
效果如下圖:

下面是當點擊按鈕后,會出現(xiàn)RuleSet的編輯器:
- using System;
 - using System.Activities;
 - using System.Windows;
 - using System.Windows.Forms;
 - using System.Workflow.Activities.Rules;
 - using System.Workflow.Activities.Rules.Design;
 - namespace Microsoft.Samples.Rules
 - {
 - // Interaction logic for PolicyDesigner.xaml
 - public partial class PolicyDesigner
 - {
 - public PolicyDesigner()
 - {
 - InitializeComponent();
 - }
 - private void button1_Click(object sender, RoutedEventArgs e)
 - {
 - // verifiy that TargetObject property has been configured
 - object targetObject = ModelItem.Properties["TargetObject"].ComputedValue;
 - if (targetObject == null)
 - {
 - System.Windows.MessageBox.Show("TargetObject needs to be configured before adding the rules");
 - return;
 - }
 - // verify that target object is correctly configured
 - InOutArgument arg = targetObject as InOutArgument;
 - if (arg == null)
 - {
 - System.Windows.MessageBox.Show("Invalid target object");
 - return;
 - }
 - // open the ruleset editor
 - Type targetObjectType = arg.ArgumentType;
 - RuleSet ruleSet = ModelItem.Properties["RuleSet"].ComputedValue as RuleSet;
 - if (ruleSet == null)
 - ruleSet = new RuleSet();
 - RuleSetDialog ruleSetDialog = new RuleSetDialog(targetObjectType, null, ruleSet);
 - DialogResult result = ruleSetDialog.ShowDialog();
 - // update the model item
 - if (result == DialogResult.OK) {
 - ModelItem.Properties["RuleSet"].SetValue(ruleSetDialog.RuleSet);
 - }
 - }
 - }
 - }
 
這樣我們就可以再WF4.0中使用該活動了,如下圖:

【編輯推薦】















 
 
 
 
 
 
 