WCF服务契约和操作重载

【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.具体配置信息如下:

<</SPAN>services>
      
<</SPAN>service behaviorConfiguration="WCFService.WCFServiceBehavior" name="WCFService.WCFService">
        
<</FONT>endpoint
          address
="http://localhost:9001/WCFService"

          binding
="wsHttpBinding"
          contract
="WCFService.IWCFOverLoadingService">
        
</</SPAN>endpoint>
        
<</FONT>endpoint
          address
="net.tcp://localhost:9002/WCFService"

          binding
="netTcpBinding"
          contract
="WCFService.IWCFOverLoadingService">
        
</</SPAN>endpoint>
        
<</FONT>endpoint
        address
="net.pipe://localhost/WCFService"

        binding
="netNamedPipeBinding"
        contract
="WCFService.IWCFOverLoadingService">
        
</</SPAN>endpoint>
        
<</SPAN>endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        
<</SPAN>endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
        
<</SPAN>endpoint address="mex" binding="mexNamedPipeBinding" contract="IMetadataExchange" />
        
<</SPAN>host>
          
<</SPAN>baseAddresses>
            
<</SPAN>add baseAddress="http://localhost:9001/"/>
            
<</SPAN>add baseAddress="net.tcp://localhost:9002/"/>
            
<</SPAN>add baseAddress="net.pipe://localhost/"/>
          
</</SPAN>baseAddresses>
        
</</SPAN>host>
      
</</SPAN>service>
    
</</SPAN>services>
    
<</SPAN>behaviors>
      
<</SPAN>serviceBehaviors>
        
<</SPAN>behavior name="WCFService.WCFServiceBehavior">
          
<</SPAN>serviceMetadata httpGetEnabled="true" />
          
<</SPAN>serviceDebug includeExceptionDetailInFaults="false" />
        
</</SPAN>behavior>
      
</</SPAN>serviceBehaviors>
    
</</SPAN>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已有的机制给出方法的别名来解决这个问题。然后给出了包括客户端等完整的测试 解决方案,客户端反序列话生成服务类默认不支持服务操作方法重载的,生成的也是服务操作的别名方法。我们在客户端要想使服务代理类支持重载,以利用重载的 优势,就需要重新修改客户端服务代理代码。

 

 

转自:http://www.cnblogs.com/quietwalk/archive/2011/08/09/2132341.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值