WCF之旅——2 Contract
2007-12-27 21:56 Jun1st 阅读(2129) 评论(3) 编辑 收藏 举报1.ServiceContract&OperationContract General
Contract定义了这一个Service能提供什么样的功能和服务(ServiceContract),也告诉了调用这一Service的客户端或者其它的Service在调用时需要提供什么样的参数信息(DataContract)。因此,在SOA架构的系统中,Contract的定义是重中之重。本文将对ServiceContract做一个简单的介绍。
在WCF中,给一个interface(或者class)添加一个[ServiceContract]的Attribute, 这个interface就成为一个面向服务的contract(service-oriented contract)。你可以使用你自己喜欢的变成语言来写这个interface,比如C#, C++, VB.Net等。只要它符合.net framework的CTS(Common Type Specification)。SeriveContract使得一个interface成为一个WCF的contract, 而不再具有类型的可见性(type’s visibility)这一属性。成为一个contract之后,它就成为一个共有的service contract. 而普通的interface对于WCF Service的调用者来说,完全是透明的的,也根本就不知道这个interface的存在。
一个interface要成一个WCF的Contract,需要给这个interface加上[ServiceContract]这一个特性(Attribute),而要这个contract成为一个有用的contract, 还需要给这个interface中希望暴露的方法加上[OperationContract]这一特性。否者,这个interface中所有的方法,对于调用这个service的client来说,都是不可见的。
Eg:
[ServiceContract] interface IMyContract1 { [OperationContract] string MyMethod1( ); } [ServiceContract] interface IMyContract2 { [OperationContract] void MyMethod2( ); } class MyService : IMyContract1,IMyContract2 { public string MyMethod1( ) {...} public void MyMethod2( ) {...} }
从示例代码钟还可以看出,WCF的多重实现(Multiple Implementation )。
2.OperationContract之Operation重载
WCF Contract的实现也支持重载,只不过需要做一些额外的工作。
//Invalid contract definition: [ServiceContract] interface ICalculator { [OperationContract] int Add(int arg1,int arg2); [OperationContract] double Add(double arg1,double arg2); }
运行上面的代码会在ServiceHost加载service的时候抛出一个:InvalidOperationException。
WCF对一个Operation提供了一个叫做Name的Attribute, 利用这个Name可以实现重载,如:
[ServiceContract] interface ICalculator { [OperationContract(Name = "AddInt")] int Add(int arg1,int arg2); [OperationContract(Name = "AddDouble")] double Add(double arg1,double arg2); }
只不过有一个不足之处是生成的Proxy的代码相应的函数名将会是AddInt和AddDouble。不过你要是愿意的话可以手动修改生成的函数,但是要确保调用了正确的internal proxy的方法。
3.ServiceContract之继承
WCF Contracts之间支持继承等操作,因此可以建立一个具有层级关系的Contracts。但是[ServiceContract]这一特性不能被继承,因此必须在每一个interface上加上这一特性。
[ServiceContract] interface ICalculator { [OperationContract] int Add(int arg1,int arg2); } [ServiceContract] interface IMyCalculator : ICalculator { [OperationContract] int Multiply(int arg1,int arg2); }
但是当把IMyCalculator这个Service暴露给Client, 并用工具生成Proxy代码时,生成大代码将不具有这种层级关系。这个问题下次说一下。