下面首先说说如何开发一个本地服务:
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.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Linq;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
namespace WorkflowConsoleApplication5
{
public sealed partial class Workflow1 : 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; }
}
然后我们向工作流中拖入一个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");
}
}
public Workflow1()
{
InitializeComponent();
}
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
Account = _accountServices.AdjustBalance(Id, Adjustment);
System.Console.WriteLine(Id+" "+Adjustment);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.Workflow.Activities;
namespace WorkflowConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
AutoResetEvent waitHandle = new AutoResetEvent(false);
ExternalDataExchangeService dataservice = new ExternalDataExchangeService();
workflowRuntime.AddService(dataservice);
AccountService accountService = new AccountService();
dataservice.AddService(accountService);
Dictionary<String, Object> dic = new Dictionary<string, object>();
dic.Add("Id",2);
dic.Add("Adjustment",23.25);
workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) {waitHandle.Set();};
workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
{
Console.WriteLine(e.Exception.Message);
waitHandle.Set();
};
WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowConsoleApplication5.Workflow1),dic);
instance.Start();
waitHandle.WaitOne();
}
}
}
}