您的位置:首页 > 其它

WF4.0实战(三):WCF服务

2010-04-18 12:25 211 查看
这篇文章,通过一个简单的WCF交互,讲解一下WF4.0中一组重要活动:Messaging,它包括:Receive
、ReceiveAndSendReply、Send、SendAndReceiveReply。这里将详细讲解ReceiveAndSendReply和SendAndReceiveReply两个活动的配置以及使用,以及它与普通的WCF的区别。

如果你了解WCF,你一定知道WCF可以缩略为ABC。A :Address (服务在哪里?),B: Binding (怎么才能访问服务?),C: Contract (提供了哪些服务?)。既然同样也是WCF服务,WF4.0中WCF服务同样也存在ABC的概念。我将一步一步通过实现WF中的wcf服务的ABC来实现这个Demo,请你注意它与普通的WCF的区别。

首先,我们定义一下用于数据交换的实体。

定义Request消息ReservationRequest

代码

1 [MessageContract(IsWrapped = false)]
2 public class ReservationResponse
3 {
4 private bool _Reserved;
5 private Branch _Provider;
6 private Guid _RequestID;
7
8 #region Constructors
9 public ReservationResponse()
10 {
11 }
12
13 public ReservationResponse(ReservationRequest request, bool reserved,
14 Branch provider)
15 {
16 _RequestID = request.RequestID;
17 _Reserved = reserved;
18 _Provider = provider;
19 }
20 #endregion Constructors
21
22 #region Public Properties
23 [MessageBodyMember]
24 public bool Reserved
25 {
26 get { return _Reserved; }
27 set { _Reserved = value; }
28 }
29
30 [MessageBodyMember]
31 public Branch Provider
32 {
33 get { return _Provider; }
34 set { _Provider = value; }
35 }
36
37 [MessageBodyMember]
38 public Guid RequestID
39 {
40 get { return _RequestID; }
41 set { _RequestID = value; }
42 }
43 #endregion Public Properties
44 }
服务端的实现

一、C(Contract )

定义这个服务具体提供了哪些服务:

1 [ServiceContract]
2 public interface ILibraryReservation
3 {
4 [OperationContract]
5 void RequestBook(ReservationRequest request);
6
7 [OperationContract]
8 void RespondToRequest(ReservationResponse response);
9 }
这里定义了两个方法:RequestBook、RespondToRequest。在普通的WCF中,一般做法是:通过一个类继承这个接口。在类中实现wcf的具体内容。而在WF4.0中,这里我将使用Messaging中的活动:ReceiveAndSendReply。

1、新建一个控制台应用程序WF3Demo:



注意:这里创建的是Console Application。而不是WorkflowConsoleApplication。

2、添加下面这些引用:

System.Activities.dll

System.ServiceModel.dll

System.ServiceModel.Activities.dll

3、创建一个自定义活动CreateResponse,它用于创建返回给客户端的ReservationResponse对象,代码如下:

1 //这种是一个自定义的活动,用于创建一个ReservationResponse对象
2 public sealed class CreateResponse : CodeActivity
3 {
4 public InArgument<ReservationRequest> Request { get; set; }
5 public InArgument<bool> Reserved { get; set; }
6 public OutArgument<ReservationResponse> Response { get; set; }
7
8 protected override void Execute(CodeActivityContext context)
9 {
10 // 打开配置文件
11 Configuration config = ConfigurationManager
12 .OpenExeConfiguration(ConfigurationUserLevel.None);
13 AppSettingsSection app =
14 (AppSettingsSection)config.GetSection("appSettings");
15
16 // 创建ReservationResponse对象
17 ReservationResponse r = new ReservationResponse
18 (
19 Request.Get(context),
20 Reserved.Get(context),
21 new Branch
22 {
23 BranchName = app.Settings["Branch Name"].Value,
24 BranchID = new Guid(app.Settings["ID"].Value),
25 Address = app.Settings["Address"].Value
26 }
27 );
28 // 将Response保存到OutArgument
29 Response.Set(context, r);
30 }
31 }
5、添加一个名字为ProcessRequest工作流,在其中拖放一个ReceiveAndSendReply。

在ProcessRequest添加如下变量:



设置Receive活动:

OperationName:RequestBook

Content: 设置Message data为request、设置Message type为ReservationRequest

ServiceContractName:ILibraryReservation

ILibraryReservation:true

设置SendReply

Content: 设置Message data为response、设置Message type 为ReservationResponse,如下图:



6、为了更好的诠释服务,在Receive活动和SendReply活动之间加入如下图活动,详细见代码。



这样我们定义好了 Contract

二、B(Binding)和[b]A(Address )[/b]

C实现之后,Binding和Address就简单了。这里Binding使用BasicHttpBinding,使用如下代码实现B和A:

1 WorkflowService service = new WorkflowService
2 {
3 Name = "LibraryReservation",
4 Body = new ProcessRequest(),
5 Endpoints =
6 {
7 new Endpoint
8 {
9 ServiceContractName="ILibraryReservation",
10 AddressUri = new Uri("http://localhost:" + adr +
11 "/LibraryReservation"),
12 Binding = new BasicHttpBinding(),
13 }
14 }
15 };
16
17 System.ServiceModel.Activities.WorkflowServiceHost wsh =
18 new System.ServiceModel.Activities.WorkflowServiceHost(service);
19
20 wsh.Open();
至此,WF4中的wcf服务就这样简单的配置好了。

客户端调用:

对于调用一般的WCF,可以通过添加service引用或者通过命令自动生成调用wcf的代码。这与WF4.0不同,这里我使用SendAndReceiveReply活动来调用WCF服务。

1、首先自定义一个活动CreateRequest,用于创建一个提交wcf服务ReservationRequest对象。

1 public sealed class CreateRequest : CodeActivity
2 {
3 public InArgument<string> Title { get; set; }
4 public InArgument<string> Author { get; set; }
5 public InArgument<string> ISBN { get; set; }
6 public OutArgument<ReservationRequest> Request { get; set; }
7 public OutArgument<string> RequestAddress { get; set; }
8
9 protected override void Execute(CodeActivityContext context)
10 {
11 // 打开配置文件,得到请求的地址
12 Configuration config = ConfigurationManager
13 .OpenExeConfiguration(ConfigurationUserLevel.None);
14 AppSettingsSection app =
15 (AppSettingsSection)config.GetSection("appSettings");
16
17 // 使用输入参数创建一个ReservationRequest对象
18 ReservationRequest r = new ReservationRequest
19 (
20 Title.Get(context),
21 Author.Get(context),
22 ISBN.Get(context),
23 new Branch
24 {
25 BranchName = app.Settings["Branch Name"].Value,
26 BranchID = new Guid(app.Settings["ID"].Value),
27 Address = app.Settings["Address"].Value
28 }
29 );
30
31 //将request保存到OutArgument中
32 Request.Set(context, r);
33
34 // 将address保存到OutArgument
35 RequestAddress.Set(context, app.Settings["Request Address"].Value);
36 }
37 }
2、添加一个名字为SendRequest的工作流,在其中拖放一个SendAndReceiveReply活动,以及一个CreateRequest活动,将CreateRequest活动拖放到Send前面。

3、在ProcessRequest添加如下变量:



在ProcessRequest添加如下参数:



4、设置Send:

OperationName:RequestBook

Content: 设置Message data为request、设置Message type为ReservationRequest

ServiceContractName:ILibraryReservation

Endpoint:Endpoint

Endpoint.Binding:BasicHttpBinding

EndpointAddress:New Uri("http://localhost/:" + requestAddress + "/LibraryReservation")

5、设置ReceiveReplyForSend

将ReceiveReplyForSend的Content的Message data设为response,将ReceiveReplyForSend的Content的Message type设为ReservationResponse

6、为了便于观察,添加几个WriteLine用于输出,如下图,详见代码:



这样设置好了客户端。

使用wcf服务:

我们只需启动ProcessRequest这个工作流来调用wcf服务:

1 IDictionary<string, object> input = new Dictionary<string, object>
2 {
3 { "Title" , "Gone with the Wind" },
4 { "Author", "Margaret Mitchell" },
5 { "ISBN", "9781416548898" }
6 };
7
8 IDictionary<string, object> output =
9 WorkflowInvoker.Invoke(new SendRequest(), input);
10 ReservationResponse resp = (ReservationResponse)output["Response"];
运行程序:

启动WCF服务。等待客户端的调用,如下图:



输入回车,启动客户端的工作流,来调用WCF服务,输入结果如下:



整个运行的过程

如下图:



总结:

这篇文章讲述了在WF4.0中使用WCF服务。WF中的WCF与普通的WCF,在原理上是一致的,但是在形式上区别很大。WF4.0中提供了一组活动,这样比直接使用WCF更加简单和直观。

欢迎加入博客园WF4.0技术交流群:51262864

下载1:XMAL工作流代码

下载2:CS工作流代码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: