WCF学习(二):契约

(原创:灰灰虫的家http://hi.baidu.com/grayworm)
契约是WCF中很重要的概念。它是用一种与平台无关的标准语法来描述WCF服务的功能。当客户端获取服务端WCF服务的时候,会根据服务端声明的契约生成客户端契约的复本,客户端和服务端通过契约来实现沟通。

一个生活中的例子:
比如KFC,它是一家快餐品牌。假设我想通过加盟的方式在我家附近开一家KFC快餐店。首先,我们要向KFC加盟代理提交加盟申请,经过资格申查后,和KFC签述加盟协议。然后,我根据协议中规定的条款在我家附开了一家KFC快餐店。KFC总部为我提供方法、技术和原材料等,我每年向KFC总部交加盟费,这样附近的朋就可以从我的KFC快餐店中获得KFC的产品和服务了。
“KFC总部”就相当于我们的WCF服务
“来吃KFC附近的朋友”相当于要获取WCF服务的客户端代码
“我开的KFC快餐店”相当于客户端的代理类
“我与KFC签定的加盟协议”相当于WCF的契约。
通过这个例子我们可以看到契约在WCF中的重要性,它就像服务端提供的“加盟协议”一样,客户端根据“加盟协议”中规定的要求在客户端生成代理类(开办加盟店),并根据加盟协议规定的权利从服务端获取服务(获取方法、技术和原材料等),这样客户端在我的加盟店里就可以直接得到KFC服务。
所以说契约是服务端与客户端进行信息交流的基础。

在WCF中包括了四种契约:服务契约,数据契约,错误契约和消息契约。在这里我们重点来看服务契约和数据契约。
在WCF中契约是以Attribute型式进行声明的。

1.用来定义服务契约的两个Attribute:
[AttributeUsage(AttributeTargets.Interface|AttributeTargets.Class,Inherited = false)]
public sealed class ServiceContractAttribute : Attribute
{
   public string Name
   {get;set;}
   public string Namespace
   {get;set;}
   //More members
}

[AttributeUsage(AttributeTargets.Method)]
public sealed class OperationContractAttribute : Attribute
{
   public string Name
   {get;set;}
   //More members
}

2.用来定义数据契约的两个Attribute:
[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Struct | AttributeTargets.Class, Inherited = false)]
public sealed class DataContractAttribute : Attribute
{
   public string Name
   {get;set;}
   public string Namespace
   {get;set;}
}

[AttributeUsage(AttributeTargets.Field|AttributeTargets.Property, Inherited = false)]
public sealed class DataMemberAttribute : Attribute
{
   public bool IsRequired
   {get;set;}
   public string Name
   {get;set;}
   public int Order
   {get;set;}
}

一、服务契约:

1.服务契约的概念
我们可以在接口或者类上声明[ServiceContract]和[OperationContract]来定义服务契约。
[ServiceContract]
interface IMyContract
{
   [OperationContract]
   string MyMethod(string text);

   //MyOtherMethod方法没有声明[OperationContract],不会成为契约的一部份
   string MyOtherMethod(string text);
}
class MyService : IMyContract
{
   public string MyMethod(string text)
   {
      return "Hello " + text;
   }
   public string MyOtherMethod(string text)
   {
      return "Cannot call this method over WCF";
   }
}

ServiceContract声明用来把.NET中的接口声明(CLR格式)映射为与平台无关的契约声明(XML格式),以向外界暴露服务访问入口ServiceContract声明与类的访问修饰符无关,即不管接口(类)的访问修饰符是public/private/protected/internal,只要把该接口(类)声明为ServiceContract,该接口(类)总会变成服务契约暴露给客户端。因为访问修饰符(public/private/protected/internal)定义的是在CLR中的访问边界,而ServiceContract定义的是在WCF中的访问边界。
在WCF中服务契约接口都需要显示声明为ServiceContract,否则,接口不会被当成WCF契约向外界暴露。
即使我们把接口声明为ServiceContract了,但该服务契约现在并不包含任何成员,我们还要在需要作为契约成员的方法上面加上OperationContractAttribute声明。像上面的代码中,MyMethod方法会作为IMyContract契约的成员向外界暴露,而MyOtherMethod方法则不会成为IMyContract契约的成员。
OperationContract 可以应用在成员方法、属性、索引器和事件上面

2.ServiceContract的NameSpace属性和Name属性
在编写WCF服务的时候,我们应当为每个服务契约设置NameSpace属性,如果为服务契约指定NameSpace属性的话,那该服务契约会默认NameSpace="http://tempuri.org"。这里NameSpace的作用与原来CLR中NameSpace的作用一样,都是为了定义一个命名空间,防止命名的冲突
如:
[ServiceContract(Namespace = "http://hi.baidu.com/grayworm")]
interface IMyContract
{...}
对Internet发布的服务契约,命名空间一般使用公司的网址进行命名,对于局域网内发布的服务契约则没有必要按照这种方式进行命名,我们可以使用更有意义单词作为NameSpace。
[ServiceContract(Namespace = "MyNamespace")]
interface IMyContract
{...}


我们还可以为服务契约指定别名。在默认的情况下,服务契约的名称与接口的名称一样,我们可以在ServiceContract声明中使用Name属性为服务契约指定别名。
[ServiceContract(Namespace="http://hi.baidu.com/grayworm",Name="GrayWormCaculate")]
public interface ICaculator
{
    [OperationContract(Name="AddInt")]
    int Add(int arg1, int arg2);
    [OperationContract(Name="AddDouble")]
    double Add(double arg1, double arg2);
}
测试结果:

WCF足迹2:契约 - Tony - Go ahead!
《图2》
从图中我们可以看出服务的名子不再是接口的名子了。

3.服务契约中的方法重载
在面向对象的思想中,我们有方法重载的概念,所谓的方法重载就是指一个类中如果两个方法的方法名相同而方法参数不同,那这两个参数就形成了重载
如:
interface ICalculator
{
   int Add(int arg1,int arg2);
   double Add(double arg1,double arg2);
}

CLR可以根据方法的能数来区分这两个方法。而在WCF世界中这种方法名相同而参数不同的形式则会引发InvalidOperationException异常,即在WCF中不支持面向对象中的方法重载。
如:
//这是种契约定义是错误的
[ServiceContract]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值