WCF服务契约基本应用技巧解读

开发 开发工具
我们今天将会通过不同的代码解读来为大家详细介绍一下WCF服务契约的分解方式以及相关设计方法,希望能给大家带来些帮助。

我们在应用WCF服务契约的时候,需要掌握一些应用技巧,才能帮助我们轻松的应用这一功能来完成各种功能需求。在这里我们就一起来看看WCF服务契约的分解与设计方法,以方便大家理解。

C++与C#均支持操作的重载,但在WCF的编程模型中,却并不支持这种技术。坦白说,在WCF的编程模型,对于面向对象的支持都是比较弱的,包括后面要介绍的继承体系与多态,都存在许多问题。因此,在服务端我们不能定义这样的WCF服务契约:

  1. [ServiceContract]   
  2. interface ICalculator   
  3. {   
  4. [OperationContract]   
  5. int Add(int arg1,int arg2);   
  6. [OperationContract]   
  7. double Add(double arg1,double arg2);   

虽然在编译时能够通过,然而一旦在装载宿主时,就会抛出InvalidOperationException异常。以ICalculator契约为例,WCF会认为是零个操作。

解决的办法是利用OperationContract特性的Name属性,例如:

  1. [ServiceContract]   
  2. interface ICalculator   
  3. {   
  4. [OperationContract(Name = "AddInt")]   
  5. int Add(int arg1,int arg2);   
  6. [OperationContract(Name = "AddDouble")]   
  7. double Add(double arg1,double arg2);   

不过采用这种方式,存在的问题是生成的代理会将Name属性指定的名称作为代理操作的方法名。这对于编程者而言,并非好的方式。所幸我们可以手动对生成的代理进行修改,将它修改为与WCF服务契约一致的操作名。由于,此时通过Name指定了操作的别名,因此,避免了装载宿主抛出的异常。

契约的继承

即使父接口标记了[ServiceContract],子接口仍然需要标记[ServiceContract],因为ServiceContractAttribute是不可继承的。服务类对服务契约的实现,与传统的C#编程没有什么区别。例如:

  1. [ServiceContract]   
  2. interface ISimpleCalculator   
  3. {   
  4. [OperationContract]   
  5. int Add(int arg1,int arg2);   
  6. }   
  7. [ServiceContract]   
  8. interface IScientificCalculator : ISimpleCalculator   
  9. {   
  10. [OperationContract]   
  11. int Multiply(int arg1,int arg2);   
  12. }   
  13. class MyCalculator : IScientificCalculator   
  14. {   
  15. public int Add(int arg1,int arg2) { return arg1 + arg2;   
  16. }   
  17. public int Multiply(int arg1,int arg2) { return arg1 * arg2;   
  18. }   

公开终结点的时候,可以对***层的契约接口公开一个单独的终结点:

  1. < service name=”MyCalculator”> < endpoint> < addressaddress=
    ”http://localhost:8001/MyCalculator/”
    > < bindingbinding=
    ”basicHttpBinding”
    > < contractcontract=” IScientificCalculator”>
     < /endpoint> < /service>  

客户端在导入如上的WCF服务契约时,会取消服务契约的继承层级,并利用OperationContract特性中的Action与ReplyAction属性,保留原来定义每个操作的契约名。但为了使客户端编程能够与服务编程保持一致,***是恢复客户端的契约层级。方法并无什么太玄妙的地方,无非就是根据服务契约层级对客户端契约进行手工修改。修改后的客户端契约及其代理的定义如下:

  1. [ServiceContract]   
  2. public interface ISimpleCalculator {   
  3. [OperationContract]   
  4. int Add(int arg1,int arg2);   
  5. }   
  6. public partial class SimpleCalculatorClient : ClientBase
    < ISimpleCalculator>, ISimpleCalculator   
  7. {   
  8. public int Add(int arg1,int arg2)   
  9. {   
  10. return Channel.Add(arg1,arg2);   
  11. } //Rest of the proxy }   
  12. [ServiceContract]   
  13. public interface IScientificCalculator : ISimpleCalculator {   
  14. [OperationContract]   
  15. int Multiply(int arg1,int arg2);   
  16. }   
  17. public partial class ScientificCalculatorClient : ClientBase
    < IScientificCalculator>,IScientificCalculator {   
  18. public int Add(int arg1,int arg2) {   
  19. return Channel.Add(arg1,arg2); }   
  20. public int Multiply(int arg1,int arg2) {   
  21. return Channel.Multiply(arg1,arg2); }   
  22. //Rest of the proxy } 

在书中还提出了所谓的代理链(Proxy Chaining)技术,实质上就是使得分别实现不同层级接口的代理类形成一个IS-A的继承关系。如上的定义,就可以使ScientificCalculatorClient继承自SimpleCalculatorClient,而不是继承ClientBase< IScientificCalculator>:

  1. public partial class SimpleCalculatorClient : 
    ClientBase
    < IScientificCalculator>, ISimpleCalculator {   
  2. public int Add(int arg1,int arg2) {   
  3. return Channel.Add(arg1,arg2);   
  4. } //Rest of the proxy }   
  5. public class ScientificCalculatorClient : SimpleCalculatorClient, 
    IScientificCalculator {   
  6. public int Multiply(int arg1,int arg2) {   
  7. return Channel.Multiply(arg1,arg2); } //Rest of the proxy } 

只有这样,如下代码才是正确的:

  1. SimpleCalculatorClient proxy1 = new SimpleCalculatorClient( );   
  2. SimpleCalculatorClient proxy2 = new ScientificCalculatorClient( );   
  3. ScientificCalculatorClient proxy3 = new ScientificCalculatorClient( ); 

以上就是对WCF服务契约的相关介绍。

【编辑推荐】

  1. WCF限流操作实际设置方式揭秘
  2. WCF实例停用基本应用技巧分享
  3. WCF分布操作应对特定操作情况
  4. WCF死锁三种不同方式介绍
  5. WCF回调契约如何进行正确定义
责任编辑:曹凯 来源: IT168
相关推荐

2010-03-01 18:11:40

WCF数据契约变更

2010-02-25 10:52:29

WCF响应服务

2010-03-01 09:48:23

WCF会话服务

2010-02-26 13:40:28

WCF消息头

2010-02-25 18:04:02

WCF IIS宿主

2010-03-01 15:40:04

WCF实例停用

2010-03-01 11:24:31

WCF面向服务

2010-02-23 15:58:57

WCF Session

2010-03-03 14:30:05

Python set类

2010-02-22 13:56:35

WCF服务契约

2010-02-24 16:58:14

WCF Session

2013-12-12 16:10:21

Lua脚本语言

2010-03-03 15:17:46

Python调用MyS

2009-12-22 10:16:54

WCF服务状态

2010-02-06 16:16:01

C++冒泡排序

2010-03-03 13:32:08

Python压缩文件

2009-11-06 15:02:47

WCF契约查询

2010-02-25 16:45:13

WCF应用技巧

2010-03-03 13:22:08

Python正则表达式

2009-12-22 09:11:31

WCF双向通信
点赞
收藏

51CTO技术栈公众号