工作流学习过程-本地服务之调用方法

先来看看工作流如何调用服务
基础代码如下:

一个实体类用于传递参数

代码
public class Account
{
public int AccountId { get; set; }
public double AcccountAmount { get; set; }
public double AccountBalance { get; set; }

public override string ToString()
{
return string.Format("AccountId:{0}\tAcccountAmount:{1}",AccountId.ToString(),AcccountAmount.ToString());
}
}

接口及服务代码:

代码
public interface ILocalService
{
Account Calculator(Account Account);
}
public class LocalService:ILocalService
{
#region ILocalService 成员

public Account Calculator(Account account)
{
return innerCalculator(account);
}

#endregion

private Account innerCalculator(Account account)
{
account.AcccountAmount
= account.AcccountAmount + account.AccountBalance;
Console.WriteLine(account);
return account;
}
}

新建一工作流
定义两个绑定属性分别为接受和返回的
加一个CodeActivity事件为codeActivity1_ExecuteCode

具体代码如下:

代码
public sealed partial class LocalServiceActivity : SequentialWorkflowActivity
{
public static DependencyProperty LocalServiceValueProperty = DependencyProperty.Register("LocalServiceValue", typeof(Account), typeof(LocalServiceActivity));

[DescriptionAttribute(
"LocalServiceValue")]
[CategoryAttribute(
"LocalServiceValue Category")]
[BrowsableAttribute(
true)]
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
public Account InputValue
{
get
{
return ((Account)(base.GetValue(LocalServiceActivity.LocalServiceValueProperty)));
}
set
{
base.SetValue(LocalServiceActivity.LocalServiceValueProperty, value);
}
}
public static DependencyProperty OutputValueProperty = DependencyProperty.Register("OutputValue", typeof(Account), typeof(LocalServiceActivity));

[DescriptionAttribute(
"OutputValue")]
[CategoryAttribute(
"OutputValue Category")]
[BrowsableAttribute(
true)]
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
public Account OutputValue
{
get
{
return ((Account)(base.GetValue(LocalServiceActivity.OutputValueProperty)));
}
set
{
base.SetValue(LocalServiceActivity.OutputValueProperty, value);
}
}

public LocalServiceActivity()
{
InitializeComponent();
}

private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
ILocalService service
= new LocalService();
OutputValue
= service.Calculator(InputValue);
}
}

新建宿主程序。执行代码

代码
private static void LocalServiceTest1()
{
BaseWorkflow.Loaclservice.Account outaccount
= new BaseWorkflow.Loaclservice.Account();

using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
AutoResetEvent waitHandle
= new AutoResetEvent(false);
workflowRuntime.WorkflowCompleted
+= delegate(object sender, WorkflowCompletedEventArgs e) {
outaccount
= (BaseWorkflow.Loaclservice.Account)(e.OutputParameters["OutputValue"]);
waitHandle.Set(); };
workflowRuntime.WorkflowTerminated
+= delegate(object sender, WorkflowTerminatedEventArgs e) { waitHandle.Set(); };

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

BaseWorkflow.Loaclservice.Account account
= new BaseWorkflow.Loaclservice.Account() { AccountId = 1001, AcccountAmount = 200,AccountBalance=50 };

paras.Add(
"InputValue", account);

WorkflowInstance instance;
instance
= workflowRuntime.CreateWorkflow(typeof(LocalServiceActivity), paras);
instance.Start();
waitHandle.WaitOne();

Console.Write(outaccount);

Console.ReadKey();
}
}

运行可观察到 服务确实被工作流调用了。而且最后结果也可以返回给宿主
那么本地服务是什么呢?
WF提供了一种服务,叫做Local Service也可以叫做Data exchange service。主要是实现工作流和宿主程序之间的通信,使工作流能够使用方法和事件通过消息与外部系统交互。 事件用于将数据发送到工作流,而工作流使用方法将数据发送到主机应用程序。 通过事件与工作流进行通信的功能提供了一种将数据发送到工作流的异步方式。
下面首先说说如何开发一个本地服务:
1.使用C#的接口定义服务契约,在接口中定义你方法和事件。并使用[ExternalDataExchangeAttribute]装饰该接口,用于说明这是一个本地服务的接口。
2.开发一个实现了该接口的类,用于实现你的逻辑。

3.创建一个工作流实例,并将该本地服务添加到工作流引擎中去:实现方法

ExternalDataExchangeService dataservice = new ExternalDataExchangeService();
workflowRuntime.AddService(dataservice);
YourService yourService
= new YourService();
dataservice.AddService(yourService);

1). 先将ExternalDataExchangeService服务对象添加到引擎。
2).再将我们自己开发的服务绑定到ExternalDataExchangeService服务中。接口具体代码

[ExternalDataExchange]
public interface ILocalService
{
Account Calculator(Account Account);
}
服务代码

public class LocalService:ILocalService
{
#region ILocalService 成员

public Account Calculator(Account account)
{
return innerCalculator(account);
}

#endregion

private Account innerCalculator(Account account)
{
account.AcccountAmount
= account.AcccountAmount + account.AccountBalance;
Console.WriteLine(account);
return account;
}
}

宿主代码

代码
private static void LocalServiceTest2()
{
BaseWorkflow.Loaclservice.Account outaccount
= new BaseWorkflow.Loaclservice.Account();

using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
AutoResetEvent waitHandle
= new AutoResetEvent(false);

ExternalDataExchangeService dataservice
= new ExternalDataExchangeService();
workflowRuntime.AddService(dataservice);
LocalService accountService
= new LocalService();
dataservice.AddService(accountService);

workflowRuntime.WorkflowCompleted
+= delegate(object sender, WorkflowCompletedEventArgs e)
{
outaccount
= (BaseWorkflow.Loaclservice.Account)(e.OutputParameters["OutputValue"]);
waitHandle.Set();
};
workflowRuntime.WorkflowTerminated
+= delegate(object sender, WorkflowTerminatedEventArgs e) { waitHandle.Set(); };

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

BaseWorkflow.Loaclservice.Account account
= new BaseWorkflow.Loaclservice.Account() { AccountId = 1001, AcccountAmount = 200, AccountBalance = 50 };

paras.Add(
"InputValue", account);

WorkflowInstance instance;
instance
= workflowRuntime.CreateWorkflow(typeof(LocalServiceActivity), paras);
instance.Start();
waitHandle.WaitOne();

Console.Write(outaccount);

Console.ReadKey();
}
}


服务定义好了,我们下面就要在工作流中条用该服务,我们有几种方式:
方法一:
Activity有一个方法OnActivityExecutionContextLoad(),我们通过该

的IServiceProvider的GetService方法来获取本地服务,代码如下:
代码
protected override void OnActivityExecutionContextLoad(IServiceProvider provider)
{
base.OnActivityExecutionContextLoad(provider);
service
= provider.GetService(typeof(ILocalService)) as ILocalService;
if (service == null)
{
throw new InvalidOperationException("Unable to retrieve ILocalService from runtime");
}
}

OnActivityExecutionContextLoad 表示活动正加载到工作流运行时

方法二:配置文件方式
方法三:使用自定义活动 
代码
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
service
= executionContext.GetService(typeof(ILocalService)) as ILocalService;
if (service == null)
{
throw new InvalidOperationException("Unable to retrieve ILocalService from runtime");
}
OutputValue
=service.Calculator(InputValue);
return base.Execute(executionContext);
}

方法四:使用CallExternalMethodActivity
interfaceType为接口名称,MethodName为调用的方法名称,该方法如何有参数则属性窗口中将会列出以供选择,返回值亦是如此,
需要指出的是。这种情况下。参数类型必须为可序列化的
其它情况不是也可以的~


 

posted on 2010-10-25 13:42  gotolovo  阅读(229)  评论(0编辑  收藏  举报