堅持學習WF(8):本地服務之調用外部方法

WF提供了一組核心服務,例如在SQL 數據庫中存儲工作流實例的執行詳細信息的持久性服務,計劃服務,事務服務和跟蹤服務。除了這些WF也提供了另外一種服務,叫做Local Service也可以叫做Data exchange service。主要是實現工作流和宿主程序之間的通信,使工作流能夠使用方法和事件通過消息與外部系統交互。 事件用于將數據發送到工作流,而工作流使用方法將數據發送到主機應用程序。 通過事件與工作流進行通信的功能提供了一種將數據發送到工作流的異步方式。本文主要講述調用外部方法的部分。

下圖說明本地通信服務如何與其主機應用程序通信:

01

下面首先說說如何開發一個本地服務:

1.使用C#的接口定義服務契約,在接口中定義你方法和事件。并使用[ExternalDataExchangeAttribute]裝飾該接口,用于說明這是一個本地服務的接口。?
2.開發一個實現了該接口的類,用于實現你的邏輯。?
3.創建一個工作流實例,并將該本地服務添加到工作流引擎中去。

我們開發一個簡單的本地服務的例子,根據AccountID來修改Balance的值,并使用三種方式來調用:?
1.定義一個Account類,代碼如下(Account.cs)

using?System;?
namespace?CaryWorkflows?
{?
??? [Serializable]?
????public?class?Account?
??? {?
????????private?Int32 _id;?
????????private?String _name = String.Empty;?
????????private?Double _balance;?

????????public?Int32 Id?
??????? {?
????????????get?{?return?_id; }?
????????????set?{ _id =?value; }?
??????? }?
????????public?String Name?
??????? {?
????????????get?{?return?_name; }?
????????????set?{ _name =?value; }?
??????? }?
????????public?Double Balance?
??????? {?
????????????get?{?return?_balance; }?
????????????set?{ _balance =?value; }?
??????? }?
??? }?
}?
2.定義一個接口,需要ExternalDataExchange屬性,代碼如下(IAccountServices.cs):

using System;
using System.Workflow.Activities;
namespace CaryWorkflows 
{[ExternalDataExchange]public interface IAccountServices{Account AdjustBalance(Int32 id, Double adjustment);}
}

3.實現該接口,代碼如下():

using System;
using System.Collections.Generic;
namespace CaryWorkflows 
{public class AccountService : IAccountServices{private Dictionary<Int32, Account> _accounts= new Dictionary<int, Account>();public AccountService(){Account account = new Account();account.Id = 101;account.Name = "Neil Armstrong";account.Balance = 100.00;_accounts.Add(account.Id, account);}public Account AdjustBalance(Int32 id, Double adjustment){Account account = null;if (_accounts.ContainsKey(id)){account = _accounts[id];account.Balance += adjustment;}return account;}       }
}
?
服務定義好了,我們下面就要在工作流中條用該服務,我們有三種方式:


在工作流中定義三個屬性:
using System;
using System.Workflow.Activities;
namespace CaryWorkflows 
{public sealed partial class BalanceAdjustmentWorkflow: SequentialWorkflowActivity{private Int32 _id;private Double _adjustment;private Account _account;private IAccountServices _accountServices;public Int32 Id{get { return _id; }set { _id = value; }}public Double Adjustment{get { return _adjustment; }set { _adjustment = value; }}public Account Account{get { return _account; }set { _account = value; }}public BalanceAdjustmentWorkflow(){InitializeComponent();}}
}
?
然后我們向工作流中拖入一個CodeActivity,Activity有一個方法OnActivityExecutionContextLoad(),我們通過該
的IServiceProvider的GetService方法來獲取本地服務,代碼如下:
protected override void OnActivityExecutionContextLoad( IServiceProvider provider)
{base.OnActivityExecutionContextLoad(provider);           _accountServices = provider.GetService(typeof(IAccountServices))as IAccountServices;if (_accountServices == null){                throw new InvalidOperationException("Unable to retrieve IAccountServices from runtime");}
}
?
在CodeActivity的ExecuteCode事件中調用本地服務的方法,代碼如下:
?
private void codeAdjustAccount_ExecuteCode(object sender, EventArgs e)
{Account = _accountServices.AdjustBalance(Id, Adjustment);
}
?
最后要將該服務添加到工作流引擎當中去,
1. 先將ExternalDataExchangeService服務對象添加到引擎。
2.再將我們自己開發的服務綁定到ExternalDataExchangeService服務中。
宿主程序的代碼如下:
using System;
using System.Collections.Generic;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using CaryWorkflows ;
namespace ConsoleLocalServices
{public class LocalServiceTest{public static void Run(){using (WorkflowRuntimeManager manager= new WorkflowRuntimeManager(new WorkflowRuntime())){AddServices(manager.WorkflowRuntime);manager.WorkflowRuntime.StartRuntime();                Dictionary<String, Object> wfArguments= new Dictionary<string, object>();              Console.WriteLine("開始....");wfArguments.Add("Id", 101);wfArguments.Add("Adjustment", -25.00);WorkflowInstanceWrapper instance = manager.StartWorkflow(
typeof(CaryWorkflows.BalanceAdjustmentWorkflow), wfArguments);manager.WaitAll(2000);Account account = instance.OutputParameters["Account"] as Account;if (account != null){Console.WriteLine( "Revised Account: {0}, Name={1}, Bal={2:C}",account.Id,
account.Name, account.Balance);}else{Console.WriteLine("Invalid Account Id\n\r");}Console.WriteLine("結束....");}} private static void AddServices(WorkflowRuntime instance){ExternalDataExchangeService exchangeService = new ExternalDataExchangeService();instance.AddService(exchangeService); exchangeService.AddService(new AccountService());}} }
這樣我們使用代碼方式調用外部方法就結束了,結果如下:
?
 
?
1.添加一個app.config到項目中,代碼如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration><configSections><section name="WorkflowRuntime" type="System.Workflow.Runtime.Configuration.WorkflowRuntimeSection,System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35" /><section name="LocalServices" type="System.Workflow.Activities.ExternalDataExchangeServiceSection, System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/></configSections><WorkflowRuntime Name="ConsoleLocalServices" ><CommonParameters><!--Add parameters common to all services--></CommonParameters><Services><!--Add core services here--></Services></WorkflowRuntime><LocalServices ><Services><!--Add local services here--><add type="CaryWorkflows.AccountService, CaryWorkflows,Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /></Services></LocalServices >
</configuration>
2.我們只要需改動宿主程序中如下部分:?
using (WorkflowRuntimeManager manager= new WorkflowRuntimeManager(new 
WorkflowRuntime("WorkflowRuntime"))); ExternalDataExchangeService exchangeService = new ExternalDataExchangeService("LocalServices");
?

1.首先自定義一個活動(AdjustAccountActivity.cs), 我們在自定義活動中獲取本地服務,并且調用其中方法,代碼如下:
using System;
using System.ComponentModel;
using System.Workflow.ComponentModel;
using System.Workflow.Activities;
namespace CaryWorkflows 
{public partial class AdjustAccountActivity : Activity{public static DependencyProperty IdProperty= System.Workflow.ComponentModel
.DependencyProperty.Register("Id", typeof(Int32), typeof(AdjustAccountActivity));[Description("Identifies the account")][Category("Local Services")][Browsable(true)][DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]public Int32 Id{get{return ((Int32)(base.GetValue(AdjustAccountActivity.IdProperty)));}set{base.SetValue(AdjustAccountActivity.IdProperty, value);}}public static DependencyProperty AdjustmentProperty = System.Workflow.ComponentModel.
DependencyProperty.Register("Adjustment", typeof(Double), typeof(AdjustAccountActivity));[Description("The adjustment amount")][Category("Local Services")][Browsable(true)][DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]public Double Adjustment{get{return ((Double)(base.GetValue(AdjustAccountActivity.AdjustmentProperty)));}set{base.SetValue(AdjustAccountActivity.AdjustmentProperty, value);}}public static DependencyProperty AccountProperty= System.Workflow.ComponentModel.
DependencyProperty.Register("Account", typeof(Account), typeof(AdjustAccountActivity));[Description("The revised Account object")][Category("Local Services")][Browsable(true)][DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]public Account Account{get{return ((Account)(base.GetValue( AdjustAccountActivity.AccountProperty)));}set{base.SetValue(AdjustAccountActivity.AccountProperty, value);}}public AdjustAccountActivity(){InitializeComponent();}protected override ActivityExecutionStatus Execute( ActivityExecutionContext
executionContext){IAccountServices accountServices =executionContext.GetService<IAccountServices>();if (accountServices == null){throw new InvalidOperationException( "fail IAccountServices from runtime");}Account = accountServices.AdjustBalance(Id, Adjustment);return base.Execute(executionContext);}} }
2.在工作流中我們將該自定義活動拖到工作流中,并設置相應的屬性即可。
?
?
使用該方式我們只需要拖一個CallExternalMethodActivity到工作流中,并且設置起相應屬性即可,如下圖:
這三種方式的執行結果都是一樣的。
上一篇:堅持學習WF(7):流程控制(Flow Control)

下一篇:堅持學習WF(9):本地服務之事件處理



本文轉自生魚片博客園博客,原文鏈接:http://www.cnblogs.com/carysun/archive/2008/05/09/CallExternalMethod.html,如需轉載請自行聯系原作者

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/396958.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/396958.shtml
英文地址,請注明出處:http://en.pswp.cn/news/396958.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c++歸并排序_合并排序法

一、合并排序(Merge Sort) 就是將多個有序數據表合并成一個有序數據表。如果參與合并的只有兩個有序表&#xff0c;那么稱為二路合并。對于一個原始的待排序序列&#xff0c;往往可以通過分割的方法來歸結為多路合并排序。二、一個待排序的原始數據序列進行合并排序的基本思路是…

golang json數組拼接

2016年06月16日 15:38:25 閱讀數&#xff1a;2575 標簽&#xff1a; golang json 數組 更多 個人分類&#xff1a; golang func main() {a : []byte({"Parents": [ "aaaaa", "bbbbbbb" ]})b : []byte({"Parents": [ "Gomez"…

php課程設計實驗心得,PHP程序設計教程實驗及課程設計

部分 教程1 基礎教程1.1 簡介1.2 WampServer安裝1.3 PHP語法1.4 變量1.5 echo和print語句1.6 數據類型1.7 字符串函數1.8 常量1.9 運算符1.10 條件語句1.11 Switch語句1.12 循環語句1.13 函數部分 教程1 基礎教程1.1 簡介1.2 WampServer安裝1.3 PHP語法1.4 變量1.5 echo和print…

DRUID連接池的簡單使用

DRUID——為監控而生的DB池 1. DRUID介紹 DRUID是阿里巴巴開源平臺上一個數據庫連接池實現&#xff0c;它結合了C3P0、DBCP、PROXOOL等DB池的優點&#xff0c;同時加入了日志監控&#xff0c;可以很好的監控DB池連接和SQL的執行情況&#xff0c;可以說是針對監控而生的DB連接池…

微習慣雖好,但是最重要的還是堅持

2019獨角獸企業重金招聘Python工程師標準>>> “微習慣”一詞是由美國的斯蒂芬蓋斯提出的。他以前是個宅男&#xff0c;懶蟲&#xff0c;為了改變自己而找到了這個方法。并且在自己身上實驗成功。養成了好的讀書、寫作和健身的習慣&#xff0c;實現了人生的華麗轉身。…

php手機端多圖預覽上傳,JS實現多圖預覽上傳的實例代碼

這篇文章主要介紹了JS實現多張圖片預覽同步上傳功能的相關資料,需要的朋友可以參考下廢話不多說了&#xff0c;直接給大家貼代碼了&#xff0c;具體代碼如下所示&#xff1a;/*** Created by liujing on 2017/5/10.*/$(document).ready(function($) {function changef(which,bu…

帶你了解zabbix整合ELK收集系統異常日志觸發告警~

今天來了解一下關于ELK的“L”-Logstash,沒錯&#xff0c;就是這個神奇小組件&#xff0c;我們都知道&#xff0c;它是ELK不可缺少的組件&#xff0c;完成了輸入&#xff08;input&#xff09;&#xff0c;過濾&#xff08;fileter&#xff09;&#xff0c;output&#xff08;輸…

用python設計學生管理系統_Python實現GUI學生信息管理系統

本文實例為大家分享了Python實現GUI學生信息管理系統的具體代碼&#xff0c;供大家參考&#xff0c;具體內容如下 項目環境&#xff1a; 軟件環境: OS:RedHat6.3 Lib:Pygtk Language:Python Support tool:Glade3 項目簡述&#xff1a; ①Glade3設計用戶的登錄窗口&#xff0c;功…

http響應頭設置

protected void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 設置響應頭數據response.setHeader(null, "HTTP/1.1 200 OK");response.setHeader("Server", "Apache-Coyote/1.1"…

java用數組實現單詞計數,MapReduce實現單詞計數原理及Java編程:WordCount

MapReduce實現單詞計數&#xff1a;WordCount單詞計數的文本信息(hello.txt)&#xff1a;hello can i help youi have a dreammaybe you can help me? 實現過程&#xff1a;? Map過程&#xff1a;并行讀取文本&#xff0c;對讀取的單詞進行Map操作&#xff0c;每個詞將會形成…

python理論知識選擇題_Python基礎自測題答案和基礎知識梳理

Python基礎自測題答案和基礎知識梳理 1.關于Python中的lambda表達式的函數體自能是單獨一條語句&#xff0c;所以答案選擇C。 例如&#xff1a;>>>g lambda x: 2*x1 g(3) 7 2.Python中的變量不需要事先聲明&#xff0c;但是需要創建和賦值&#xff0c;否則你怎么用&a…

STM32f4 ARM Bootloader

參考資料&#xff1a; 基于ARM 的嵌入式系統Bootloader 啟動流程分析 Bootloader 詳解 ( 代碼環境 | ARM 啟動流程 | uboot 工作流程 | 架構設計) Android系統啟動流程 -- bootloader 在main()之前&#xff0c;IAR都做了啥&#xff1f; STM32 IAP程序 源碼 和測試代碼 有詳細的…

查找算法之順序查找

參考&#xff1a; 1. 順序查找 | 博客園 基本思想&#xff1a; 順序查找&#xff0c;就是從第一個元素開始&#xff0c;按索引順序遍歷待查找序列&#xff0c;直到找出給定目標或者查找失敗。 特點&#xff1a; 1. 對待查序列&#xff08;表&#xff09;無要求 -- 待查找序列可…

matlab kfda,SVD與KFDA相結合人臉識別-matlab-畢業論文

XXXXxx畢業設計(論文)最高達到88%。當在抽取的特征維數為39&#xff0c;PCA空間的投影維數為110的情況下&#xff0c;隨著訓練樣本個數的增加&#xff0c;LDA的識別情況如表4所示表4 ORL人臉庫LDA測試結果(2)訓練樣本數 識別率/% 識別時間/S3 68.2 52.3594 87.92 31.5315 88.00…

python數據預測_python時間序列預測股票走勢

提示&#xff1a;這只是個訓練模型&#xff0c;技術不具備實際意義&#xff0c;入市需謹慎。 首先調用tushare包 import tushare as ts import pandas as pd import matplotlib.pyplot as plt 查自己比較感興趣的股票&#xff0c;這里我查找的是新能源/燃料電池/氫燃料&#xf…

30.Android之百度地圖簡單學習

今天用了下百度地圖&#xff0c;簡單寫了一個例子&#xff0c;記錄下。 一、申請AK&#xff08;API Key&#xff09; 要想使用百度地圖sdk&#xff0c;就必須申請一個百度地圖的api key。申請流程挺簡單的。 首先注冊成為百度的開發者&#xff0c;然后打開http://lbsyun.baidu.…

在datatable中,在指定位置插入列

假如dataset ds 里面已經存在了數據&#xff0c;當我們想在datatable中插入一列數據&#xff0c;可以用以下方法實現&#xff1a;ds.Tables[0].Columns.Add("star");ds.Tables[0].Columns["star"].SetOrdinal(0);這樣“star”列就添加到datatable的第一列了…

python爬取b站彈幕_爬取B站彈幕并且制作詞云

目錄 SRE實戰 互聯網時代守護先鋒&#xff0c;助力企業售后服務體系運籌帷幄&#xff01;一鍵直達領取阿里云限量特價優惠。 爬取彈幕 1. 從手機端口進入網頁爬取找到接口 2.代碼 import requests from lxml import etree import numpy as np urlhttps://api.bilibili.com/x/v1…

myeclipse始終build workspace

之前我的myeclipse運行某個項目的時候&#xff0c;總是不停的buildworkspace&#xff0c;而且稍微改動一個(不管是java類還是jsp)都會加載接近1分鐘甚至更久&#xff0c;從網上搜了好久&#xff0c;先總結下搜的多數方法 1、叫你去掉.project文件的一段話 <buildCommand>…