继上一节WCF分布式开发步步为赢系列的(4):WCF服务可靠性传输配置与编程开发,本节我们继续学习WCF分布式开发步步为赢的第(5)节:服务契约与操作重载。这里我们首先讲解OOP面向对象的编程中方法重载,重载的意义,WCF服务编程开发如何实现操作重载,随后是代码分析部分,给出了服务端服务契约定义和实现操作重载的注意的问题和实现过程,然后详细介绍了客户端实现操作重载的方式。最后是本文的总结部分。本节的结构是:【1】重载概念【2】操作重载【3】代码实现分析【4】运行结果【5】总结

【1】重载概念:

【1.1】什么是重载(OverLoad):

所谓重载是指同一个方法名可以对应着多个方法的实现。这些方法的名字相同,但是方法的参数的类型不同。这就是方法重载的概念。函数方法类和对象的应用尤其重要。

 

 方法重载要求编译器能够唯一地确定调用一个方法时应执行哪个方法代码,即采用哪个方法实现。确定方法实现时,要求从方法参数的个数和类型上来区分。这就是说,进行方法重载时,要求同名方法在参数个数上不同,或者参数类型上不同。否则,将无法实现重载。
    关于重载一定要注意:重载方法的参数类型和参数个数一定要不同(即:要么参数的类型不同,要么参数的个数不同,要么参数的类型和个数都不同),否则,编译器就不知道该调用那个方法了。

方法重载的好处就是相同的方法,带来不同的结果和实现,这里我们可以根据传递参数的不同来决定调用飞方法。这是编译时多态的一种实现机制。

【1.2】C#类方法重载示例:

我们这里给出一个简单的c#语言实现的方法重载的列子,这里对于SayHelloOverLoading方法,同一个类里给出的三个方法的参数个数不同。内部实现也不同。具体代码如下:


//3.面向对象里的类,如何实现操作重载,和WCF服务类里的操作重载做对比
    public class ClassOverLoading
    {
        public ClassOverLoading()
        {          }
        //掩饰方法重载,分别实现三个方法,C#等面向对象的语言提供了方法重载机制的支持。
        public string SayHelloOverLoading()
        { 
            //编写代码
            return "Hello,This an C# class overloading demo";
        }
        //类里的方法重载不需要别名
        public string SayHelloOverLoading(string name)
        {
            //编写代码
            return "Hello:" + name + "This an C# class overloading demo";
        }         public string SayHelloOverLoading(string firstName, string lastName)         {
            //编写代码
            return "Hello:" + firstName + lastName + "This an C# class overloading demo";
        }     }

【2】操作重载:

【2.1】操作重载:

WCF服务支持核心的Web 服务协议,同样其元数据交换也是基于XML语言描述,客户端通过WSDL文件来了解服务方法相关的信息,包括参数的个数、类型、返回值、调用顺序等重要信息。由于WSDL不支持方法的重载,因此我们的WCF服务操作重载就无法通过WSDL暴露给客户端。如果我们在服务契约里定义了方法的重载,编译可以正常通过,但是启动服务宿主就会抛出System.InvalidOperationException异常,如下图:

因此我们不能在WCF服务类了定义和实现方法重载,否则无法暴露为服务操作。

【2.2】解决办法:

WCF给我们提供了一个解决办法,让我们可以在WCF服务类里使用服务操作的重载。WCF定义了一个机制OperationContract,使用OperationContract特性的Name属性,为操作指定别名:


[AttributeUsage(AttributeTargets.Method)]
public sealed class OperationContractAttribute : Attribute
{
   public string Name
   {get;set;}    //更多成员 }

【3】代码实现分析:

下面我们来给出一个具体的WCF服务实现操作重载,包括服务定义、宿主配置、客户端引用和测试的完整过程。

【3.1】服务契约:

定义了服务契约IWCFOverLoadingService,分别给出SayHelloOverLoading操作契约的3种不同定义和WCFService服务类里的实现。具体代码如下:


    //1.服务契约,操作契约重载
    [ServiceContract(Namespace = "http://www.cnblogs.com/frank_xl/")]
    public interface IWCFOverLoadingService
    {
        //操作契约
        [OperationContract(Name = "SayHelloOverLoading1")]
        string SayHelloOverLoading();
        //操作契约
        [OperationContract(Name = "SayHelloOverLoading2")]
        string SayHelloOverLoading(string name);
        //操作契约
        [OperationContract(Name = "SayHelloOverLoading3")]
        string SayHelloOverLoading(string firstName, string lastName);     }
    //2.服务类,集成接口。实现契约
    public class WCFService : IWCFOverLoadingService
    {
        //实现接口定义的方法
        public string SayHelloOverLoading()
        {
            Console.WriteLine("Hello! ,This an overloading demo for WCF Service ");
            return "Hello! This an overloading demo for WCF Service  ";
        }
        //实现接口定义的方法
        public string SayHelloOverLoading(string name)
        {
            Console.WriteLine("Hello! {0},This an overloading demo WCF Service ", name);
            return "Hello! " + name + ", This an overloading demo for WCF Service ";
        }
        //实现接口定义的方法
        public string SayHelloOverLoading(string firstName, string lastName)
        {
            Console.WriteLine("Hello! {0}    {1},This an overloading demo WCF Service", firstName, lastName);
            return "Hello! " + firstName + " " + lastName + ", This an overloading demo for WCF Service "; ;
        }
    }

【3.2】托管宿主:

自定义托管宿主使用配置文件来定义服务的终结点和元数据交换节点,服务的交换行为等其他属性也在配置文件里给出,我们配置了三种不同的数据服务通信方式,分别是http、tcp、IPC.具体配置信息如下:


<services>
      <service behaviorConfiguration="WCFService.WCFServiceBehavior" name="WCFService.WCFService">
        <endpoint
          address="http://localhost:9001/WCFService"
          binding="wsHttpBinding"
          contract="WCFService.IWCFOverLoadingService">
        </endpoint>
        <endpoint
          address="net.tcp://localhost:9002/WCFService"
          binding="netTcpBinding"
          contract="WCFService.IWCFOverLoadingService">
        </endpoint>
        <endpoint
        address="net.pipe://localhost/WCFService"
        binding="netNamedPipeBinding"
        contract="WCFService.IWCFOverLoadingService">
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
        <endpoint address="mex" binding="mexNamedPipeBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:9001/"/>
            <add baseAddress="net.tcp://localhost:9002/"/>
            <add baseAddress="net.pipe://localhost/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFService.WCFServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

【3.3】客户端服务引用:

我们来分别添加对服务端的引用,首先启动托管宿主程序。然后使用Visual Studio2008工具直接添加服务引用,你也可以使用svcUtil.exe工具,如图所示:

客户端输入服务的基地址,查找服务,成功够我们可以看到服务契约的信息,这里显示的3个操作名称已经不同,实际上这里给出的是三个不同名称的服务方法。输入命名空间,确定即可完成。

【3.4】代理代码:

客户端反序列化生成的服务契约等信息,我们查看操作契约对应的客户端方法名称以及改变,这样一来,客户端就没有实现对应的方法重载,也就不能使用重载带来的优势,也即是编译时多态的特性。手动更改客户端服务代理类和服务契约代码,使之支持操作方法重载,代码如下:


public interface IWCFOverLoadingService {
        
        [System.ServiceModel.OperationContractAttribute(Name = "SayHelloOverLoading1" ,Action="http://www.cnblogs.com/frank_xl/IWCFOverLoadingService/SayHelloOverLoading1", ReplyAction="http://www.cnblogs.com/frank_xl/IWCFOverLoadingService/SayHelloOverLoading1Respon" +
            "se")]
        string SayHelloOverLoading();         [System.ServiceModel.OperationContractAttribute(Name = "SayHelloOverLoading2", Action = "http://www.cnblogs.com/frank_xl/IWCFOverLoadingService/SayHelloOverLoading2", ReplyAction = "http://www.cnblogs.com/frank_xl/IWCFOverLoadingService/SayHelloOverLoading2Respon" +
            "se")]
        string SayHelloOverLoading(string name);         [System.ServiceModel.OperationContractAttribute(Name = "SayHelloOverLoading3", Action = "http://www.cnblogs.com/frank_xl/IWCFOverLoadingService/SayHelloOverLoading3", ReplyAction = "http://www.cnblogs.com/frank_xl/IWCFOverLoadingService/SayHelloOverLoading3Respon" +
            "se")]
        string SayHelloOverLoading(string firstName, string lastName);
    }
    

这样我们客户端方法也支持操作方法的重载特性。

【3.5】客户端测试代码:

为了测试操作契约,我们在客户端应用里添加了部分的测试代码,这里为了测试服务端定义的不同的操作。我们分组按照协议给出了测试的代码:


            //实例化客户端服务代理Tcp
            ServiceOverLoadingTcp.WCFOverLoadingServiceClient wcfServiceProxyTcp =
                new ServiceOverLoadingTcp.WCFOverLoadingServiceClient("WSHttpBinding_IWCFOverLoadingService1");
            Console.WriteLine("Test call service using TCP--------------------.");
            //通过代理调用SayHelloOverLoading服务,分别传递不同的参数,进行测试
            Console.WriteLine(wcfServiceProxyTcp.SayHelloOverLoading());
            Console.WriteLine(wcfServiceProxyTcp.SayHelloOverLoading("Frank Xu Lei"));
            Console.WriteLine(wcfServiceProxyTcp.SayHelloOverLoading("Lei", "Xu"));             //实例化客户端服务代理Http
            ServiceOverLoadingHttp.WCFOverLoadingServiceClient wcfServiceProxyHttp =
                new ServiceOverLoadingHttp.WCFOverLoadingServiceClient("NetTcpBinding_IWCFOverLoadingService");
            Console.WriteLine("Test call service using Http-------------------");
            //通过代理调用SayHelloOverLoading服务,分别传递不同的参数,进行测试
            Console.WriteLine(wcfServiceProxyHttp.SayHelloOverLoading());
            Console.WriteLine(wcfServiceProxyHttp.SayHelloOverLoading("Frank Xu Lei"));
            Console.WriteLine(wcfServiceProxyHttp.SayHelloOverLoading("Lei", "Xu"));             //Debuging
            Console.WriteLine("Press any key to continue");
            Console.Read();

【4】运行结果:

这里分别调用三种服务操作,进行测试。运行的结果如图所示:

【5】总结:

以上就是本节对WCF服务操作重载的介绍,包括一般重载的基本定义和c#语言中简单的方法重载的实现。然后介绍了WCF操作重载的实现机制、局限性和解决办法,服务契约默认不支持操作方法重载,我们可以利用WCF已有的机制给出方法的别名来解决这个问题。然后给出了包括客户端等完整的测试解决方案,客户端反序列话生成服务类默认不支持服务操作方法重载的,生成的也是服务操作的别名方法。我们在客户端要想使服务代理类支持重载,以利用重载的优势,就需要重新修改客户端服务代理代码。 另外给出本节的实例代码供大家参考:

/Files/frank_xl/WCFServiceOverLoadFrankXuLei.rar

参考资料:

1.《函数重载》:http://baike.baidu.com/view/534068.htm

WCF分布式开发步步为赢(5)服务契约与操作重载的更多相关文章

  1. WCF分布式开发步步为赢(15):错误契约(FaultContract)与异常处理(ExceptionHandle)

    今天学习WCF分布式开发步步为赢系列的15节:错误契约(FaultContract)与异常处理(ExceptionHandle).本节内容作为WCF分布式开发的一个重要知识点,无论在学习还是项目中都应 ...

  2. WCF分布式开发步步为赢(6):WCF服务契约继承与分解设计

    上一节我们学习了WCF分布式开发步步为赢(5)服务契约与操作重载部分.今天我们来继续学习WCF服务契约继承和服务分解设计相关的知识点.WCF服务契约继承有何优势和缺点?实际项目里契约设计有什么原则和依 ...

  3. WCF分布式开发步步为赢(7):WCF数据契约与序列化

    本节继续学习WCF分布式开发步步为赢(7):WCF数据契约与序列化.数据契约是WCF应用程序开发中一个重要的概念,毫无疑问实现客户端与服务端数据契约的传递中序列化是非常重要的步骤.那么序列化是什么?为 ...

  4. WCF分布式开发步步为赢(4):WCF服务可靠性传输配置与编程开发

    今天继续WCF分布式开发步步为赢系列的第4节:WCF服务可靠性传输配置与编程开发.这个章节,我们要介绍什么是WCF服务的可靠性传输,随便介绍网络协议的概念,Web Service为什么不支持可靠性传出 ...

  5. WCF分布式开发步步为赢(3)WCF服务元数据交换、配置及编程开发

    今天我们继续WCF分布式开发步步为赢(3)WCF服务元数据交换.配置及编程开发的学习.经过前面两节的学习,我们了解WCF分布式开发的相关的基本的概念和自定义宿主托管服务的完整的开发和配置过程.今天我们 ...

  6. WCF分布式开发步步为赢(13):WCF服务离线操作与消息队列MSMQ

    之前曾经写过一个关于MSMQ消息队列的文章:WCF分布式开发必备知识(1):MSMQ消息队列 ,当时的目的也是用它来作为学习WCF 消息队列MSMQ编程的基础文章.在那篇文章里,我们详细介绍了MSMQ ...

  7. WCF分布式开发步步为赢(11):WCF流处理(Streaming)机制

    WSE3.0框架提供了数据优化传输机制,WSE3.0构建Web服务安全(4):MTOM消息传输优化和文件上传.下载 疑问里进行了介绍.WCF同样也提供了流操作来支持大数据对象的传输和处理优化机制,今天 ...

  8. WCF分布式开发步步为赢(10):请求应答(Request-Reply)、单向操作(One-Way)、回调操作(Call Back).

    WCF除了支持经典的请求应答(Request-Reply)模式外,还提供了什么操作调用模式,他们有什么不同以及我们如何在开发中使用这些操作调用模式.今天本节文章里会详细介绍.WCF分布式开发步步为赢( ...

  9. WCF分布式开发步步为赢(8):使用数据集(DataSet)、数据表(DataTable)、集合(Collection)传递数据

    数据集(DataSet).数据表(DataTable).集合(Collection)概念是.NET FrameWork里提供数据类型,在应用程序编程过程中会经常使用其来作为数据的载体,属于ADO.NE ...

随机推荐

  1. C# 堆和栈的区别-该文转自:http://www.itcodes.cn/746.html | 程序人生

    理解堆与栈对于理解.NET中的内存管理.垃圾回收.错误和异常.调试与日志有很大的帮助.垃圾回收的机制使程序员从复杂的内存管理中解脱出来,虽然绝大多数的C#程序并不需要程序员手动管理内存,但这并不代表程 ...

  2. Tutorial: Analyzing sales data from Excel and an OData feed

    With Power BI Desktop, you can connect to all sorts of different data sources, then combine and shap ...

  3. 6.Knockout.Js(加载或保存JSON数据)

    前言 Knockout可以实现很复杂的客户端交互,但是几乎所有的web应用程序都要和服务器端交换数据(至少为了本地存储需要序列化数据),交换数据最方便的就是使用JSON格式 – 大多数的Ajax应用程 ...

  4. Oracle 11gR2 Database和Active Data Guard迁移案例

    客户一套核心系统由一台Oracle Database 11.2.0.3.4单机和一台Active Data Guard组成,分别运行在两台PC服务器上,Oracle Linux 5.8 x86_64b ...

  5. js jquery 判断IE有效方法

    jquery1.9以前 $.browser.msie jquery1.9更高版本 $.browser.msie = /msie/.test(navigator.userAgent.toLowerCas ...

  6. ASP.NET&AJAX&JSON - 动态读取数据

    因为之前帮WM组做了一个delivery的dashboard,大概用了3周的时间,.net也忘了差不多了,ajax和highchart表也是现学的,蛮费劲!总算也搞出来了.发帖纪录一下. 1. 前台A ...

  7. 低噪声APD偏置电路

    低噪声APD偏置电路 APD电源摘要:该电路产生并控制光通信中雪崩光电二极管(APD)的低噪声偏置电压.该可变电压通过控制APD的雪崩增益,优化光纤接收器的灵敏度特性.该电路采用低噪声.固定频率PWM ...

  8. oracle11g创建数据库最后一步确定时弹出无法创建目录

    总的说是Windows7的权限问题 Windows7 dos命令下输入dbca创建数据库,因为权限问题,数据库将无法完成.所以还是在开始程序中打开dbca创建数据库比较好. Windows7 dos以 ...

  9. 转载 SQL Server 2008 R2 事务与隔离级别实例讲解

    原文:http://blog.itpub.net/13651903/viewspace-1082730/ 一.事务简介 SQL Server的6个隔离级别中有5个是用于隔离事务的,它们因而被称作事务隔 ...

  10. Linux 下的类似Windows下Everything的搜索工具

    Windows NTFS有个超级快的搜索工具Everything,非常好用,Linux下有几个类似的命令行工具,太难用了,推荐一个catfish,类似Everything,有GUI,可以自定义一个快捷 ...