WF4.0 应用篇(一) Activity

 

流程设计器可加载的数据

 

 

Activity 对象

计器基于对象加载

Activity XAML

设计器基于文件加载,也可以将XAML字串生成Activity加载

ActivityBuilder 对象

计器基于对象加载

ActivityBuilder XAML

设计器基于文件加载,也可以将XAML字串生成ActivityBuilder对象加载

最好不要将XAML字串生成Activity加载,因为这时对象是DynamicActivity

 

 

Activity结构

 

 

组合Activity

  • 不需要定义类
  • 由现有的Activity拼接而成
  • 设计时不可添加动态Argument
  • 可以由XAML表示,在XAML中没的Class标记,XAML结构与代码组合的结构一一对应

 

Activity

public Activity getActivity()

{

Sequence root = new Sequence{ DisplayName = "root" };

 

Variable<string> myVariable = new Variable<string>{ Name= "myVariable", Default="wxwinter"};

 

root.Variables.Add(myVariable);

 

Sequence body = new Sequence { DisplayName = "body" };

 

WriteLine writeLine = new WriteLine();

 

writeLine.Text = myVariable;

 

body.Activities.Add(writeLine);

 

root.Activities.Add(body);

 

return root;

}

宿主

WorkflowApplication instance = new WorkflowApplication(getActivity());

 

instance.Run();

结果

结构

图例

XAML

<Sequence mc:Ignorable="sap"

DisplayName="root"

sap:VirtualizedContainerService.HintSize="257,311"

mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces"

xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities"

xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"

xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<Sequence.Variables>

<x:Reference>__ReferenceID0</x:Reference>

</Sequence.Variables>

<sap:WorkflowViewStateService.ViewState>

<scg:Dictionary x:TypeArguments="x:String, x:Object">

<x:Boolean x:Key="IsExpanded">True</x:Boolean>

</scg:Dictionary>

</sap:WorkflowViewStateService.ViewState>

<Sequence DisplayName="body" sap:VirtualizedContainerService.HintSize="235,187">

<sap:WorkflowViewStateService.ViewState>

<scg:Dictionary x:TypeArguments="x:String, x:Object">

<x:Boolean x:Key="IsExpanded">True</x:Boolean>

</scg:Dictionary>

</sap:WorkflowViewStateService.ViewState>

<WriteLine sap:VirtualizedContainerService.HintSize="213,63">

<InArgument x:TypeArguments="x:String">

<VariableValue x:TypeArguments="x:String">

<VariableValue.Variable>

<Variable x:TypeArguments="x:String" x:Name="__ReferenceID0" Default="wxd" Name="myVariable" />

</VariableValue.Variable>

</VariableValue>

</InArgument>

</WriteLine>

</Sequence>

</Sequence>

 

 

 

 

静态 Activity

  • 需要定义类,Activity具有类名
  • 在类中使用Execute方法实现功能
  • 设计时不可添加动态Argument
  • 可Variables,Activities,Body等在设计时可添加内容的区域
  • 可以由XAML表示,在XAML中没的Class标记,XAML只表示该Activity与其属性,不表示其内部
  • XAML脱离该类无法运行

 

 

Activity

public sealed class 2¬?Activity : CodeActivity

{

 

public InArgument<string> myValue { get; set; }

 

 

protected override void Execute(CodeActivityContext context)

{

 

string text = context.GetValue(this.myValue);

 

System.Console.WriteLine(text);

}

}

宿主

Dictionary<string, object> dic = new Dictionary<string, object>();

dic.Add("myValue", "wxwinter");

WorkflowApplication instance = new WorkflowApplication(getActivity(),dic);

 

instance.Run();

结果

结构

图例

XAML

<静态Activity mc:Ignorable="sap"

myValue="{x:Null}"

sap:VirtualizedContainerService.HintSize="200,22"

mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces"

xmlns="clr-namespace:ActivityStructure.code;assembly=ActivityStructure.code"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities"

xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />

 

动态Activity

 

DynamicActivityProperty

ICustomTypeDescriptor

DynamicActivity

DynamicActivity<TResult>

 

  • DynamicActivity可以通过向Properties中添加DynamicActivityProperty以实现动态添加InArgument,OutArgument属性
  • DynamicActivity可以通过Implementation关联要执行的Activity
  • DynamicActivity的Properties中的InArgument可在创建实例时为其传入值
  • DynamicActivity的Properties中的OutArgument可在实例完成时得到传出值
  • DynamicActivity关联的Activity内部可以通过[VisualBasicValue]方式与Properties中的直绑定
  • DynamicActivity不能保存为XAML,但可以将DynamicActivity的Implementation保存为XAML,该XAML没的参数.在使用该XAML创建实例时还要动态为其创建参数

 

Activity

public Activity getActivity()

{

DynamicActivity dynamicActivity = new DynamicActivity();

dynamicActivity.DisplayName = "myDynamicActivity";

 

dynamicActivity.Properties.Add(new DynamicActivityProperty

{

Name = "inValueA",

Type = typeof(InArgument<int>),

Value = new InArgument<int>()

});

 

dynamicActivity.Properties.Add(new DynamicActivityProperty

{

Name = "inValueB",

Type = typeof(InArgument<int>),

Value = new InArgument<int>()

});

 

dynamicActivity.Properties.Add(new DynamicActivityProperty

{

Name = "outValue",

Type = typeof(OutArgument<int>),

Value = new OutArgument<int>()

});

 

dynamicActivity.Implementation =()=>createActivity();

 

return dynamicActivity;

 

}

Activity createActivity()

{

 

return new Sequence

{

 

Activities =

{

new Assign<int>

{

To = new ArgumentReference<int> { ArgumentName = "outValue" },

Value = new VisualBasicValue<int>("(inValueA + inValueB) * 100")

},

}

};

}

宿主

Dictionary<string, object> dic = new Dictionary<string, object>();

dic.Add("inValueA", 123);

dic.Add("inValueB", 456);

 

IDictionary<string, object> results = WorkflowInvoker.Invoke(getActivity(), dic);

 

foreach (var v in results)

{

System.Console.WriteLine("{0}:{1}", v.Key, v.Value);

}

结果

结构

图例

 

无参数,只是Implementation部分,所以动态绑定部分有验证提升

 

XAML

无参数,只是Implementation部分

 

<Sequence mc:Ignorable="sap" sap:VirtualizedContainerService.HintSize="222,146" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<sap:WorkflowViewStateService.ViewState>

<scg:Dictionary x:TypeArguments="x:String, x:Object">

<x:Boolean x:Key="IsExpanded">True</x:Boolean>

</scg:Dictionary>

</sap:WorkflowViewStateService.ViewState>

<Assign x:TypeArguments="x:Int32" sap:VirtualizedContainerService.HintSize="200,22" Value="[(inValueA + inValueB) * 100]">

<Assign.To>

<OutArgument x:TypeArguments="x:Int32">

<ArgumentReference x:TypeArguments="x:Int32" ArgumentName="outValue" />

</OutArgument>

</Assign.To>

</Assign>

</Sequence>

 

 

 

 

 

 

实现 Activity

 

 

  • 通过继承Activity,构建Implementation实现.
  • 只能通过继承Activity,其他从Activity派生的Activity不允许操作Implementation
  • 设计时不可添加动态Argument
  • 可以由XAML表示,在XAML中没的Class标记,XAML只表示该Activity与其属性,不表示其内部
  • XAML脱离该类无法运行

 

 

Activity

public class º¦Ì?Activity :Activity

{

 

 

public InArgument<string> myValueA { get; set; }

 

public InArgument<string> myValueB { get; set; }

 

 

 

protected override void CacheMetadata(ActivityMetadata metadata)

{

Implementation = () => createActivity();

base.CacheMetadata(metadata);

}

 

Activity createActivity()

{

 

Sequence sequence = new Sequence();

 

sequence.Activities.Add(new WriteLine { Text = new VisualBasicValue<String>("myValueA") });

sequence.Activities.Add(new WriteLine { Text = new VisualBasicValue<String>("myValueB") });

 

return sequence;

 

}

 

 

}

宿主

Dictionary<string, object> dic = new Dictionary<string, object>();

dic.Add("myValueA", "wxwinter");

dic.Add("myValueB", "wxd");

WorkflowApplication instance = new WorkflowApplication(getActivity(), dic);

 

instance.Run();

结果

结构

图例

XAML

<实现Activity mc:Ignorable="sap"

myValueA="{x:Null}"

myValueB="{x:Null}"

sap:VirtualizedContainerService.HintSize="200,22"

mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces"

xmlns="clr-namespace:ActivityStructure.code;assembly=ActivityStructure.code"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities"

xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />

 

 

 

 

构建 Activity

 

 

IDebuggableWorkflowTree

ActivityBuilder

ActivityBuilder<TResult>

 

  • 使用ActivityBuilder
  • 设计器基可直接加载ActivityBuilder对象
  • 设计器基可直接加载ActivityBuilder的XAML文件
  • 使用ActivityBuilder的Implementation构建Activity
  • ActivityBuilder的Properties中的InArgument可在创建实例时为其传入值
  • ActivityBuilder的Properties中的OutArgument可在实例完成时得到传出值
  • ActivityBuilder关联的Activity内部可以通过[VisualBasicValue]方式与Properties中的直绑定
  • 生成的XAML具有Class标记,但并不会生成类,该标记是给VS生成Dll时使用的
  • 设计时可添加动态Argument
  • VS设计器使用的就是这种方式,designerView.Load(new ActivityBuilder())就产生了一个与VS一样的环节
  • ActivityBuilder的XAML可用ActivityXamlServices生成Activity,是DynamicActivity类型

 

 

 

Activity

public ActivityBuilder getActivityBuilder()

{

//1

Sequence body = new Sequence();

 

//1.1

WriteLine writeLineA = new WriteLine();

writeLineA.DisplayName = "writeLineA";

writeLineA.Text = "hello lzm";

body.Activities.Add(writeLineA);

 

 

//1.2

WriteLine writeLineB = new WriteLine();

writeLineB.DisplayName = "writeLineB";

writeLineB.Text = new VisualBasicValue<string> { ExpressionText = "inputX+inputY" };

body.Activities.Add(writeLineB);

 

//1.3

Assign<string> assign = new Assign<string>();

assign.DisplayName = "assign";

assign.To = new VisualBasicReference<string> { ExpressionText = "output" };

assign.Value = new VisualBasicValue<string> { ExpressionText = "inputX+inputY" };

body.Activities.Add(assign);

 

//1.4

WriteLine writeLineC = new WriteLine();

writeLineC.DisplayName = "writeLineC";

writeLineC.Text = new VisualBasicValue<string> { ExpressionText = "output" };

body.Activities.Add(writeLineC);

 

//2

ActivityBuilder activityBuilder = new ActivityBuilder();

//2.1

activityBuilder.Name = "wxwinterClass";

//2.1

activityBuilder.Properties.Add(new DynamicActivityProperty { Name = "inputX", Type = typeof(InArgument<string>) });

activityBuilder.Properties.Add(new DynamicActivityProperty { Name = "inputY", Type = typeof(InArgument<string>) });

activityBuilder.Properties.Add(new DynamicActivityProperty { Name = "output", Type = typeof(OutArgument<string>) });

//2.3

activityBuilder.Implementation = body;

 

//3

return activityBuilder;

 

}

string getXamlStringFromActivityBuilder(ActivityBuilder activityBuilder)

{

string xamlString = "";

 

StringBuilder stringBuilder = new StringBuilder();

 

System.IO.StringWriter stringWriter = new System.IO.StringWriter(stringBuilder);

 

System.Xaml.XamlSchemaContext xamlSchemaContext = new System.Xaml.XamlSchemaContext();

 

System.Xaml.XamlXmlWriter xamlXmlWriter = new System.Xaml.XamlXmlWriter(stringWriter, xamlSchemaContext);

 

 

System.Xaml.XamlWriter xamlWriter = System.Activities.XamlIntegration.ActivityXamlServices.CreateBuilderWriter(xamlXmlWriter);

 

System.Xaml.XamlServices.Save(xamlWriter, activityBuilder);

 

xamlString = stringBuilder.ToString();

 

return xamlString;

 

}

public Activity getActivity()

{

string xamlString = getXamlStringFromActivityBuilder(getActivityBuilder());

 

System.IO.StringReader stringReader = new System.IO.StringReader(xamlString);

 

Activity activity = System.Activities.XamlIntegration.ActivityXamlServices.Load(stringReader);

 

return activity;

 

}

宿主

System.Collections.Generic.Dictionary<string, object> p = new System.Collections.Generic.Dictionary<string, object>();

p.Add("inputX", "wxd");

p.Add("inputY", "lzm");

 

System.Collections.Generic.IDictionary<string, object> r = WorkflowInvoker.Invoke(getActivity(), p, new TimeSpan(0, 0, 0));

foreach (var item in r)

{

System.Console.WriteLine(item);

}

结果

结构

图例

XAML

<Activity mc:Ignorable="sap" x:Class="wxwinterClass" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<x:Members>

<x:Property Name="inputX" Type="InArgument(x:String)" />

<x:Property Name="inputY" Type="InArgument(x:String)" />

<x:Property Name="output" Type="OutArgument(x:String)" />

</x:Members>

<sap:VirtualizedContainerService.HintSize>275,495</sap:VirtualizedContainerService.HintSize>

<mva:VisualBasic.Settings>Assembly references and imported namespaces serialized as XML namespaces</mva:VisualBasic.Settings>

<Sequence sap:VirtualizedContainerService.HintSize="235,455" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces">

<sap:WorkflowViewStateService.ViewState>

<scg:Dictionary x:TypeArguments="x:String, x:Object">

<x:Boolean x:Key="IsExpanded">True</x:Boolean>

</scg:Dictionary>

</sap:WorkflowViewStateService.ViewState>

<WriteLine DisplayName="writeLineA" sap:VirtualizedContainerService.HintSize="213,63" Text="hello lzm" />

<WriteLine DisplayName="writeLineB" sap:VirtualizedContainerService.HintSize="213,63" Text="[inputX+inputY]" />

<Assign x:TypeArguments="x:String" DisplayName="assign" sap:VirtualizedContainerService.HintSize="213,22" To="[output]" Value="[inputX+inputY]" />

<WriteLine DisplayName="writeLineC" sap:VirtualizedContainerService.HintSize="213,63" Text="[output]" />

</Sequence>

</Activity>

 

 

 

 

VS的Activity

VS设计器使用了的是[构建 Activity]创建流程

但与[构建 Activity]方式又有不同,VS不是基于ActivityBuilder的XAML的实例创建流程的,而是将

ActivityBuilder的XAML生成了Dll,方式如下

将ActivityBuilder的XAML中的Class标记做为类名,

将ActivityBuilder的XAML由

 

 

<Activity mc:Ignorable="sap" x:Class="WorkflowConsoleApplication2.Workflow1" this:Workflow1.myProperty="myOut" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Xml" xmlns:s3="clr-namespace:System;assembly=System.Core" xmlns:sa="clr-namespace:System.Activities;assembly=System.Activities" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:this="clr-namespace:WorkflowConsoleApplication2" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<x:Members>

<x:Property Name="myIn" Type="InArgument(x:String)" />

<x:Property Name="myOut" Type="OutArgument(x:String)" />

<x:Property Name="myProperty" Type="x:String" />

</x:Members>

<sap:VirtualizedContainerService.HintSize>305,326</sap:VirtualizedContainerService.HintSize>

<mva:VisualBasic.Settings>Assembly references and imported namespaces for internal implementation</mva:VisualBasic.Settings>

<Sequence sad:XamlDebuggerXmlReader.FileName="e:\myconfig\documents\visual studio 2010\Projects\WorkflowConsoleApplication2\WorkflowConsoleApplication2\Workflow1.xaml" sap:VirtualizedContainerService.HintSize="265,286">

<sap:WorkflowViewStateService.ViewState>

<scg3:Dictionary x:TypeArguments="x:String, x:Object">

<x:Boolean x:Key="IsExpanded">True</x:Boolean>

</scg3:Dictionary>

</sap:WorkflowViewStateService.ViewState>

<WriteLine sap:VirtualizedContainerService.HintSize="243,63" Text="[myIn]" />

<Assign sap:VirtualizedContainerService.HintSize="243,59">

<Assign.To>

<OutArgument x:TypeArguments="x:String">[myOut]</OutArgument>

</Assign.To>

<Assign.Value>

<InArgument x:TypeArguments="x:String">wxwinter</InArgument>

</Assign.Value>

</Assign>

</Sequence>

</Activity>

 

转换为Activity格式的XAML

<?xml version="1.0" encoding="utf-8"?>

<this:Workflow1 this:myProperty="myOut" mva:VisualBasic.Settings="Assembly references and imported namespaces for internal implementation" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Xml" xmlns:s3="clr-namespace:System;assembly=System.Core" xmlns:sa="clr-namespace:System.Activities;assembly=System.Activities" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:this="clr-namespace:WorkflowConsoleApplication2;assembly=WorkflowConsoleApplication2" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<this:Workflow1.Implementation>

<Sequence sad:XamlDebuggerXmlReader.FileName="e:\myconfig\documents\visual studio 2010\Projects\WorkflowConsoleApplication2\WorkflowConsoleApplication2\Workflow1.xaml">

<WriteLine Text="[myIn]" />

<Assign>

<Assign.To>

<OutArgument x:TypeArguments="x:String">[myOut]</OutArgument>

</Assign.To>

<Assign.Value>

<InArgument x:TypeArguments="x:String">wxwinter</InArgument>

</Assign.Value>

</Assign>

</Sequence>

</this:Workflow1.Implementation>

</this:Workflow1>

 

并将其作为资源文件存在Dll中,在运行时加载该XAML()

生成的XAML具有Class标记,但并不会生成类,该标记是给VS生成Dll时使用的

 

这样做的好处是该工作流是强类型

 

弱类型方式

Dictionary<string, object> dic = new Dictionary<string, object>();

dic.Add("myIn", "wxd");

 

var ins = new WorkflowApplication(new Workflow1(), dic);

ins.Completed = (p) =>

{

string s = p.Outputs["myOut"].ToString();

System.Console.WriteLine(s);

};

 

ins.Run();

强类型方式

Workflow1 w = new Workflow1();

w.myIn = "wxd";

w.myProperty = "lzm"; //可以对属性赋值

 

var ins = new WorkflowApplication(w);

 

ins.Completed = (p) =>

{

string s = p.Outputs["myOut"].ToString();

System.Console.WriteLine(s);

};

 

ins.Run();

 

 

 

 

posted @ 2010-04-09 15:22  WXWinter(冬)  阅读(4523)  评论(4编辑  收藏  举报