《WF编程》系列之28 - 本地通信事件:CallExternalMethodActivity
《WF编程》系列之28 - 本地通信事件:CallExternalMethodActivity
4.2 本地通信事件
让工作流和外部世界进行交互也并不是什么难事,因为WF本身就内置了一些活动来完成这样的工作.
这一节我们来讨论一下可以和宿主进程提供的本地服务进行通信的活动们
为了能让本地通信可以工作,我们需要以.NET接口的形式定义一个合同.在这个接口中会包含一些方法和事件,工作流可以通过这些方法来调用本地服务,而本地服务则可以触发这些会被工作流处理的事件.
还是关于bug跟踪的例子.有时候我们需要更详细的描述一个bug,比如一张截图.工作流可以向宿主索取这种额外需要的文档.也许宿主会自动上传文档,但实际上更多的情形是,宿主会提醒一个用户:”Hi,您需要提供bug的更详细信息!”.接着,工作流会等待图片被上传(或许几秒钟,或许几天).图片上传完毕后,宿主可以通过一个事件来通知工作流.下面的接口定义了一个服务合同. ExternalDataExchange特性将接口标识为本地通信服务,而且凭借这个标识,Runtime还会将这个接口识别为服务合同.
interface IBugService
{
bool RequestUpload(Guid id, string userName);
event EventHandler UploadCompleted;
}
接下来介绍可以和这个接口交互的两个活动: CallExternalMethod和HandleExternalEvent.
4.2.1 CallExternalMethodActivity
CallExternalMethod活动可以调用本地服务上的方法.我们需要做的仅仅是设置这个活动的属性:
首先应该设置的是InterfaceType属性,设计器会通过我们设置的接口来自动发现服务中所有可用的方法.一旦我们把InterfaceType设置为之前定义的接口,我们就可以为MethodName属性选择需要调用的方法.设计器还会在属性面板中列出该方法需要的参数.我们可以将这些输入参数和方法的返回值绑定到工作流的域或属性.譬如图中的_newBug就是工作流的一个域.
为了使CallExternalMethod活动工作,我们需要在工作流Runtime中添加一个ExternalDataExchangeService,然后再向ExternalDataExchangeService中添加一个本地服务BugFlowService(BugFlowService类实现了IBugService接口).
ExternalDataExchangeService dataService = new ExternalDataExchangeService();
workflowRuntime.AddService(dataService);
BugFlowService bugService = new BugFlowService();
dataService.AddService(bugService);
CallExternalMethod活动包含一个MethodInvoking事件,这个事件会在活动调用外部方法之前触发,我们可以利用这个事件来动态的操作这些参数:
{
if (string.IsNullOrEmpty(_newBug.NewBug.Description))
{
_newBug.NewBug.Description = " 这家伙太懒了,什么都没留下.";
}
}