《WF编程》系列之13 – XAML激活
2.3.3 XAML激活
在有些环境中,编译过程会变成一种负担.想象一下,数据库中包含了上千个为特定用户量身打造的工作流定义.在这种情形下,我们也许想要避免总是创建新的程序集而引起的性能消耗.而我们需要的就是以最低的开销加载工作流,然后执行.幸运的是,这正是以纯XAML方式编写工作流的优点.
如果要激活之前创建的工作流,我们需要调整一下XOML文件.之前我们在XOML文件中使用x:Class特性来告诉编译器工作流定义中类型的名称,而现在编译器并不会创建新的类,因为XAML根本不会经历编译阶段.请注意之前我们通过WorkflowMarkupSerializer创建的XAML并不包含x:Class特性.
激活机制只对完全定义在工作流标记中的工作流有效.因为不用经过编译阶段,我们不得不放弃一些XAML名称空间提供的功能(如内嵌代码).对于CLR对象 来说,XAML是有效的XML序列化格式,所以激活机制只不过直接从XAML创建了一个对象层次结构(object hierarchy).
激活通过WorkflowRuntime中的CreateWorkflow方法来启用.我们要使用CreateWorkflow方法的另外一个重载,要传递的参数不是类型对象,而使一个XmlReader,我们要通过XmlReader来把工作流标记以流的方式传给Runtime.
using (WorkflowRuntime runtime = new WorkflowRuntime())
{
using (AutoResetEvent waitHandle = new AutoResetEvent(false))
{
runtime.WorkflowCompleted += delegate { waitHandle.Set(); };
runtime.WorkflowTerminated += delegate { waitHandle.Set(); };
TypeProvider typeProvider = new TypeProvider(runtime);
typeProvider.AddAssembly(Assembly.GetExecutingAssembly());
runtime.AddService(typeProvider);
WorkflowInstance instance = runtime.CreateWorkflow(reader);
instance.Start();
waitHandle.WaitOne();
}
}
编译XOML文件时,我们可以指定一个程序集引用来指向包含自定义活动WriteLineActivity的程序集.当激活工作流时,Runtime仍然需要定位自定义活动的程序集,这时我们需要使用一个TypeProvider服务.TypeProvider会保持工作流激活所需的程序集引用,Runtime依赖TypeProvider服务来确定类型和程序集.在上边的代码中,我们以程序集引用的方式添加了正在执行的程序集.
在使用激活工作流之前还需要考虑版本带来的影响.当工作流编译之后,我们可以提供程序集版本和其它元数据来标识程序集,也可以提供一个强名称来唯一地标识程序集并防止程序集被篡改.但是在另一方面,XOML文件没有内置的版本结构,所以如果我们需要版本或者密码保护,我们需要写一些自定义代码.
纯XAML小结
我们讲述了几种生成纯XAML解决方案.如果我们需要一个轻量级的方式来创建新的工作流,那么采用纯XAML方式并结合工作流激活功能是合适的选择.但如果我们需要用C#或者Visual Basic代码扩充工作流,纯XAML方式就不能很好的工作了.下一节,我们看一下结合XAML和代码.




Windie Chai @ 豆瓣
windiechai @ Twitter
windiechai @ 新浪微博
看了你的帖子受益非浅!
系列之12中最后一段生成的XAML中没有内部activity。如果我要激活的话,必须要手动写入内部活动顺序嘛?(就像你系列之13开头的XAML中多了<otc:WriteLineActivity Message="Hello, workflow!"/,xmlns的声明也不一样>)
我的意思是能不能用你写的序列化后的XAML直接激活运行?
@ryan 1
可以激活,但是请注意,工作流是一个黑盒,它内部的活动是向外公开���,所以序列化之后看不到任何活动,但是由于序列化后的xoml中包含了程序集引用和命名空间,仍然可以激活运行,激活机制一旦生成了该工作流的实例,那么该工作流自然就可以执行其内部的活动。
本文和系列12中的示例并不是同一个示例。
runtime.AddService(typeProvider);
xoml"); –这个是什么???
WorkflowInstance instance = runtime.CreateWorkflow(reader);
@QFSoft
很明显,我也不知道那是什么,也不知道它是怎么出现的,现在去掉了。
不知道楼主是不是这个情况. 运行纯xoml的工作流(没有x class)时候, 必须把.xoml file的文件属性的 buildAction 改为"None",才能build成功.
我又个问题是怎么样通过代码动态更改 buildAction?
迫切等待.
@pengp
抱歉这么久才回答你的问题,答案是“是的”,buildAction必须为None。
但buildAction应该不能被你的代码来修改,它是vs或者编译器的工作��而不是程序集的工作。
郁闷 XAML 就是看不懂!
请问一下,WorkflowInstance instance = runtime.CreateWorkflow(reader)中的reader是在哪里定义的呢?还有runtime.WorkflowCompleted += delegate可以不要参数吗?
楼主辛苦!不过有一点我不太明���,在上边的例子中我们如何确定激活的是哪一个工作流呢?
@0606reader是一个XmlReader,并没有在上面的代码中出现,它的作用是读取一个xml文件。
@hao!传入CreateWorkflow的XmlReader读取的是哪个xml文件,启动的就是哪个工作流。
[...] 《WF编程》系列之13 – XAML激活 [...]