WinVista新技术 WCF开发指南之构建服务( 二 )


下面是一些可能的服务地址:

http://localhost:8001
http://localhost:8001/MyService
net.tcp://localhost:8002/MyService
net.pipe://localhost/MyPipe
net.msmq://localhost/private/MyService

四. 服务合同

在WCF中,所有的服务都暴露合同 。合同是一种描述服务所实现功能的平台中立的标准的方式 。WCF定义了四种类型的合同:

· 服务合同描述你可以在服务上执行哪些操作 。

· 数据合同定义哪些数据类型被传入和传出服务 。WCF为内置类型定义隐式合同,例如int和string,但是你可以容易地为定制类型定义显式的选入式数据合同 。

· 错误合同定义哪些错误将被该服务所激发,以及该服务怎样处理错误信息和把如何把它们传播到客户端 。

· 消息合同允许服务直接与消息进行交互 。消息合同可以被类型化或非类型化,并且有点类似于CLR中的迟绑定调用 。不过,消息合同很少为SOA开发者所用 。

在这4种类型的合同中,本文将集中讨论服务合同 。

你可以使用ServiceContractAttribute来定义一个服务合同,并且你可以把该属性应用于一个接口或一个类,如列表1(见本文相应下载源码)所示 。

服务合同独立于接口或类可见性-公共或内部可见性是一个CLR概念,而不是WCF概念 。在一个内部接口上应用ServiceContractAttribute将把该接口暴露为一个公共服务合同(可以跨越服务边界进行消费) 。没有ServiceContractAttribute的话,该接口对WCF客户端是不可见的,这与面向服务的宗旨一致(服务边界是显式的) 。为了强制实现这一点,所有的合同必须是严格选入的 。

OperationContractAttribute仅能被应用到方法(而不是属性,索引器或事件,这都是一些CLR概念)中 。OperationContractAttribute把一个合同方法暴露为在服务合同上执行的一种逻辑操作 。该接口上的其它不具有OperationContractAttribute属性的方法不会成为合同的一部分 。这可以强制实现显式的服务边界,并且,对于操作本身来说,保持一种选入模型 。注意,合同操作独立于方法可见性 。列表1展示了通过定义一个合同接口把服务合同与其实现分离开来的最好应用 。

另外,你还可以直接把ServiceContractAttribute和OperationContractAttribute应用于类,在这种情况下,WCF使用OperationContractAttribute从类中推断出一个服务合同和方法 。这是一种应该尽量避免使用的技术:

//尽量避免使用
[ServiceContract]
class MyService
{
 [OperationContract] //可见性并不要紧
 string MyMethod(string text)
 {
return "Hello "text;
 }
 public string MyOtherMethod(string text)
 {
return "Cannot call this method over WCF";
 }
}
这个ServiceContractAttribute把CLR接口(或推断的接口)映射到一个技术中立的WCF合同上 。通过派生和实现多个带有ServiceContractAttribute的接口,单个类可以支持多个合同 。类能够通过隐式或显式方式实现这个接口,因为该方法可见性对WCF没有任何影响 。然而,存在许多实现约束:避免使用参数化的构造器,因为WCF仅使用默认的构造器 。尽管该类能够使用内部属性,索引器和静态成员,但是没有WCF客户端能够存取它们 。

五. 宿主

每个WCF服务必须宿主在一个Windows进程中(称为宿主进程) 。单个宿主进程可以宿主多个服务,而相同的服务类型可以宿主在多个进程中 。WCF并不要求是否该宿主进程也是客户端进程 。

显然,应该有一个独立的进程支持错误和安全的隔离 。另外,谁提供进程或调用哪种类型的进程都不是实质性的问题 。这个宿主可以由IIS或Windows Vista中的Widows活动服务(WAS)或由开发者作为应用程序的一部分来提供 。

推荐阅读