这篇文章主要是实现一个分布式的酒店订房功能。主要阐述如何通过WCF加WF实现一个分布式系统模型。
这个Demo的场景说明:
一家酒店将房间信息存储在SQL Server数据库中,酒店的工作人员根据客户的要求的房间类型,查询出房间的价格,告诉用户价格,决定是否订房。
分布式订房系统系统设计图:

上图说明:
1、通过ADO.NET Data Serivce访问数据库,它使用ADO.NET Entity DataModel和WCF Data Service构建一个数据库增删查改的WCF服务。
2、WF4.0 Service是WF4.0的WCF服务,通过WCF访问ADO.NET Data Serivce。
3、WF4.0 Client和.NET Windows client是两个客户端,他们的功能是相同的,通过Internet访问WF4.0 Service。
传统的分布式设计图:

比较一下两张图片,你会发现:
1、传统的数据库访问是使用SQL Helper。
2、将业务逻辑宿主在Web Service中,现在是宿主在WF4.0和WCF结合的服务中。
实现:下面我将一步一步实现这个Demo
1、创建数据库,就一张表如下图:

2、创建ADO.NET Data Service:
新建一个RentRoom空项目,添加一个ASP.Net应用程序RentRoomDataService,删除所有的aspx和cs文件。添加一个ADO.NET Entity DataModel项目,将其命名为myModel.edmx。如下图:

选择Generates from database,点下一步,新建一个连接字符串,如下图:

点击OK,点击next,选择表Room,点击完成,如下图:

在RentRoomDataService中添加一个WCF Data Service,命名为MyWcfDataService.svc,如下图:

修改MyWcfDataService.svc.cs代码:
1
public
class
MyWcfDataService : DataService
<
RentRoomEntities2
>
2
{
3
//
This method is called only once to initialize service-wide policies.
4
public
static
void
InitializeService(DataServiceConfiguration config)
5
{
6
config.SetEntitySetAccessRule(
"
*
"
, EntitySetRights.All);
7
config.SetServiceOperationAccessRule(
"
*
"
, ServiceOperationRights.All);
8
}
9
}
这样ADO.NET Data Service创建完成。
3、创建RentRoomCustomActivities,它包括三个自定义活动:
先添加MyWcfDataService服务引用,如下图:

GetInput用于接收等待用户输入,代码如下:
1
public
class
GetInput : CodeActivity
2
{
3
OutArgument
<
string
>
data;
4
public
OutArgument
<
string
>
Data
5
{
6
get
{
return
data; }
7
set
{ data
=
value; }
8
}
9
10
protected
override
void
Execute(CodeActivityContext context)
11
{
12
string
input
=
Console.ReadLine();
13
context.SetValue(data, input);
14
}
15
}
CheckPrice用于查询房间的价格,调用ADO.NET Data Service,代码如下:
1
public
class
CheckPrice : CodeActivity
2
{
3
InArgument
<
string
>
roomID;
4
public
InArgument
<
string
>
RoomID
5
{
6
get
{
return
roomID; }
7
set
{ roomID
=
value; }
8
}
9
10
OutArgument
<
decimal
>
roomPrice;
11
public
OutArgument
<
decimal
>
RoomPrice
12
{
13
get
{
return
roomPrice; }
14
set
{ roomPrice
=
value; }
15
}
16
17
protected
override
void
Execute(CodeActivityContext context)
18
{
19
string
carId
=
RoomID.Get(context);
20
21
String urlstr
=
"
http://localhost:40438/MyWcfDataService.svc
"
;
22
CarRentalReference.RentRoomEntities2 proxy
=
new
CarRentalReference.RentRoomEntities2(
new
Uri(urlstr));
23
24
var query
=
(from c
in
proxy.Room
25
where
c.RoomID
==
carId
26
select c).First();
27
28
decimal
?
price
=
query.RoomPrice;
29
30
context.SetValue(RoomPrice, price);
31
}
32
33
34
}
BookRoom用于确定订房,调用ADO.NET Data Service,代码如下:
1
public
class
BookRoom : CodeActivity
2
{
3
InArgument
<
string
>
roomId;
4
public
InArgument
<
string
>
RoomId
5
{
6
get
{
return
roomId; }
7
set
{ roomId
=
value; }
8
}
9
10
protected
override
void
Execute(CodeActivityContext context)
11
{
12
string
carId
=
RoomId.Get(context);
13
14
String urlstr
=
"
http://localhost:40438/MyWcfDataService.svc
"
;
15
CarRentalReference.RentRoomEntities2 proxy
=
new
CarRentalReference.RentRoomEntities2(
new
Uri(urlstr));
16
17
var query
=
(from c
in
proxy.Room
18
where
c.RoomID
==
carId
19
select c);
20
21
foreach
(CarRentalReference.Room room
in
query)
22
{
23
room.Quantity
=
room.Quantity
-
1
;
24
proxy.UpdateObject(room);
25
proxy.SaveChanges();
26
break
;
27
}
28
29
}
30
31
32
}
RentRoomCustomActivities创建完成。
4、创建RentRoomWFService。这是设计图上的WF4.0 Service。
这个服务由两个ReceiveAndSendReply构成,第一个ReceiveAndSendReply,如下图:

第二个ReceiveAndSendReply,如下图:

ReceiveAndSendReply具体的设置参考:WF4.0实战(三):WCF服务 、WF4.0 基础篇 (二十七) WCF Workflow Service 在WCF中使用WF
在Program.cs中写启动这个服务的代码,如下:
1
static
void
Main(
string
[] args)
2
{
3
string
baseAddress
=
"
http://localhost:8090/RentRoomService
"
;
4
5
6
7
using
(WorkflowServiceHost host
=
8
new
WorkflowServiceHost(
new
Workflow1(),
new
Uri(baseAddress)))
9
{
10
host.Description.Behaviors.Add(
new
11
ServiceMetadataBehavior() { HttpGetEnabled
=
true
});
12
host.AddDefaultEndpoints();
13
14
host.Open();
15
Console.WriteLine(
"
Rent Room service listening at:
"
+
16
baseAddress);
17
Console.WriteLine(
"
Press ENTER to exit
"
);
18
Console.ReadLine();
19
host.Close();
20
}
21
}
22
}
这样RentRoomWFService完成。
5、客户端RentRoomWidowsClient
启动RentRoomWFService,在RentRoomWidowsClient添加RentRoomWFService引用,如下图:

使用下面代码模拟订房:
1
ServiceReference1.RentRoomDataContract contract
=
new
ServiceReference1.RentRoomDataContract();
2
contract.RoomId
=
"
gaoji
"
;
3
contract.CustomerId
=
"
012
"
;
4
ServiceReference1.ServiceClient proxy
=
new
ServiceReference1.ServiceClient();
5
decimal
?
test
=
proxy.CheckPrice(contract);
6
bool
?
test1
=
proxy.BookRoom(
"
012
"
);
6、客户端RentRoomWFClient
定义一个工作流调用WF服务,详见RentRoomWFClient.Workflow1.xaml。
启动RentRoomWFService服务,如下图:

运行效果图:

本文参考:
WF4.0 基础篇 (二十七) WCF Workflow Service 在WCF中使用WF
ADO.NET Data Service
Introducing WF4.0: Building Distributed Apps with WF 4.0 and WF 4.0 Services
代码:/Files/zhuqil/RentRoomWFClient.rar
数据库:/Files/zhuqil/db.rar
原文链接: http://www.cnblogs.com/zhuqil/archive/2010/04/27/DistributedApps.html