免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
WCF之旅(5):面向服務(wù)架構(gòu)(SOA)和面向?qū)ο缶幊蹋∣OP)的結(jié)合——如何實現(xiàn)Service Contract的重載(Overloading)

對于.NET重載(Overloading)——定義不同參數(shù)列表的同名方法(順便提一下,我們但可以在參數(shù)列表上重載方法,我們甚至可以在返回類型層面來重載我們需要的方法——頁就是說,我們可以定義兩個具有相同參數(shù)列表但不同返回值類型的兩個同名的方法。不過這種廣義的Overloading不被我們主流的.NET 語言所支持的——C#, VB.NET, 但是對于IL來說,這這種基于返回值類型的Overloading是支持的)。相信大家聽得耳朵都要起老繭了。我想大家也清楚在編寫傳統(tǒng)的XML Web Service的時候,Overloading是不被支持的。

原因很簡單,當我們用某種支持.NET的高級語言寫成的程序被相應(yīng)的編譯器編譯成Assembly的過程中,不單單是我們的Source Code會被變成IL Code,在Assembly中還會生成相應(yīng)的原數(shù)據(jù)Metadata——這些Metadata 可以被看看是一張張的Table。這些Table存儲了定義了主要3個方面的信息——構(gòu)成這個Assembly文件的信息;在Assembly中定義的Type及其相關(guān)成員的信息;本引用的Assembly 及Type的信息。這些完備的Metadata成就了Assembly的自描述性(Self-Describing),也只是有了這些Metadata,使.NET可以很容易地根據(jù)方法參數(shù)的列表甚至是返回值得類型來判斷調(diào)用的究竟了那個方法。

而對于XML Web Service,它的標準實際上是基于XML的,近一步說,一個XML Web Service是通過一個一段XML來描述的,而這個描述XML Web Service的XML,我們稱之為WSDL(Web Service Description Language)。在WSDL中,Web Service的一個方法(Method)對應(yīng)的是一個操作(Operation),Web Service 所有的Operation定義在WSDL中的portType Section。我們可以參照下面一段XML,它是從一個完整的WSDL中截取下來的。我們可以看到,portType包含了Web Service定義的所有Operation,每個Operation由一個operation XML Element表示??催^我前面Blog的讀者應(yīng)該知道,從消息交換(Message Exchange)的層面上講,一個Operation實際上體現(xiàn)的是一種消息交換的模式(Message Exchange Pattern——MEP)。所以我們完全可以通過一定消息交換的輸入消息(Input Message)和輸出(Output Message )定義一個Operation。而WSDL也是這樣做的。(這里順便提一下,Output Message部僅僅對應(yīng)一個方法的Return Value,還包括表明ref 和out的Parameter)。除了定義進行消息交互的Message的格式(一般通過XSD)之外,每個Operation還應(yīng)該具有一個能夠為一標識該Operation的ID,這個ID通過name XML Attribute來定義。通常的情況下,Operation的Name使用Web Service的方法名——這就是在傳統(tǒng)XML Web Service不可以使用Overloading的原因。

<wsdl:portType name="ICalculator">
  
<wsdl:operation name="AddWithTwoOperands">
    
<wsdl:input wsaw:Action="http://tempuri.org/ICalculator/AddWithTwoOperands" message="tns:ICalculator_AddWithTwoOperands_InputMessage" />
    
<wsdl:output wsaw:Action="http://tempuri.org/ICalculator/AddWithTwoOperandsResponse" message="tns:ICalculator_AddWithTwoOperands_OutputMessage" />
  
</wsdl:operation>
  
<wsdl:operation name="AddWithThreeOperands">
    
<wsdl:input wsaw:Action="http://tempuri.org/ICalculator/AddWithThreeOperands" message="tns:ICalculator_AddWithThreeOperands_InputMessage" />
    
<wsdl:output wsaw:Action="http://tempuri.org/ICalculator/AddWithThreeOperandsResponse" message="tns:ICalculator_AddWithThreeOperands_OutputMessage" />
  
</wsdl:operation>
</wsdl:portType>

和XML Web Service,WCF也面臨一樣的問題——我覺得我們可以把WCF看成.NET平臺下新一代的Web Service。雖然現(xiàn)有XML Web Service現(xiàn)在具有廣泛的使用——尤其在構(gòu)建跨平臺性的分布是應(yīng)用和進行系統(tǒng)集成上面,但是從Microsoft已經(jīng)明確提出WSE 3.0將是最后一個Version的WSE,所以,現(xiàn)有的Web Service將會全面的過渡到WCF。WCF到底是什么東西,我在前面的文章中不斷地提出這個問題,在這里我們從 另外一個方面來看待WCF。我們知道W3C定義了一系列關(guān)于WS的規(guī)范Specification,成為WS-* Specification。這一系列的Specification定義了建立在XML和SOAP標準之上的基于如何將一個可互操作系統(tǒng)(Interoperable System)的各個方面的標準,比如WS-Messaging,WS-Security,WS-Transaction等等。而WCF則可以看成是這一整套Specification的實現(xiàn)。但是這種實現(xiàn)最終還是落實到我們.NET編程上。我們可以把WS-Specification和我們的基于.NET語言的編程看成是兩種截然不同的編程模型(Programming Model)。WCF的功能則是把這兩種不同的編程模型統(tǒng)一起來,實現(xiàn)他們之間的一個Mapping——可以把WCF看成一個Adapter。

回到我們的Overloading上面來,Overloading是.NET Framework原生支持的。通過Overloading,我們可以使用同名的方法來定義不同的操作,從而使我們的Code顯得更加優(yōu)雅(Elegant)。要是Overloading在WCF中可以使用,WCF必須提供這樣的一個Mapping——是被重載的具有相同方法的的方法Mapping到不同的Operation上。而提供著一個功能的就是ServiceContract。下面我們來結(jié)合一個Sample來看如何在WCF中使用Overloading。

沿用我們的Calculator的應(yīng)用,現(xiàn)在我們做一個加法器,它具有兩個Operation——兩書相加和三數(shù)相加。這兩個方法都用一個名稱Add。

1.下面是Solution的結(jié)構(gòu)。不像前面的結(jié)構(gòu),這這里我們沒有把Service Contract單獨提取出來,供Client和Service供用。因為我們現(xiàn)在模擬的是,Service完全由一個外部的第三方提供,Service 已經(jīng)確定,不能根據(jù)Client的具體要求來修改Service。Source Code從這里下載。


2.Service端的Code:

Service Contract: Artech.OverloadableContract.Service ICalculator.cs.

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;

namespace Artech.OverloadableContract.Service
{
    [ServiceContract]
   
public interface ICalculator
    
{
        [OperationContract(Name 
= "AddWithTwoOperands")]
       
double Add(double x, double y);

       [OperationContract(Name 
= "AddWithThreeOperands")]
       
double Add(double x, double y, double z);
    }

}

這個Service Contract定義了Overloading的兩個Add方法,為了把這兩個方法映射到兩個不同的Operation,我們通過System.ServiceModel.OperationAttribute 的Name屬性為Operation指定一個Name——AddWithTwoOperands 和AddWithThreeOperands。

下面是Service的Code,簡單地實現(xiàn)了Service Conract,無須贅言。

using System;
using System.Collections.Generic;
using System.Text;

namespace Artech.OverloadableContract.Service
{
    
public class CalculatorService:ICalculator
    
{
        
ICalculator Members
    }

}

3.Hosting Service

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    
<system.serviceModel>
      
        
<behaviors>
            
<serviceBehaviors>
                
<behavior name="calculatorServiceBehavior">
                    
<serviceMetadata httpGetEnabled="true" />
                
</behavior>
            
</serviceBehaviors>
        
</behaviors>
      
        
<services>
            
<service behaviorConfiguration="calculatorServiceBehavior" name="Artech.OverloadableContract.Service.CalculatorService">
                
<endpoint binding="basicHttpBinding" contract="Artech.OverloadableContract.Service.ICalculator" />
                
<host>
                    
<baseAddresses>
                        
<add baseAddress="http://localhost:1234/calcuator" />
                    
</baseAddresses>
                
</host>
            
</service>
        
</services>
    
</system.serviceModel>
</configuration>

Program.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using Artech.OverloadableContract.Service;

namespace Artech.OverloadableContract.Hosting
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            
using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
            
{
                host.Open();
                Console.WriteLine(
"Calculator service has begun to listen
 
");
                Console.Read();
            }

        }

    }

}

相關(guān)的已經(jīng)在前面的文章中說過,代碼很簡單,沒有什么好說的。

現(xiàn)在我們來啟動這個Host,在IE中通過鍵入這個地址http://localhost:1234/calcuator?wsdl看看生成的WSDL是什么樣子。

通過截圖我們可以看到,在WSDL的portType Section,兩個Operation的Name已經(jīng)成功地變成了我們在OperationContract Attrbute中指定的那樣。


4.接下來我們?yōu)镃lient端添加一個Server Reference。就像在使用XML Web Service中添加Web Reference一樣,添加Server Reference會為Client添加相應(yīng)的客戶端代碼——倒入的Service Contract,繼承自ClientBase<T>的Proxy Class, 和相應(yīng)的Confugration。下面我們來分析這些通過添加Service Reference而生成的Code。

Imported Service Contract:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel""3.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(ConfigurationName
="Artech.OverloadableContract.Client.CalculatorService.ICalculator")]
    
public interface ICalculator
    
{
        
        [System.ServiceModel.OperationContractAttribute(Action
="http://tempuri.org/ICalculator/AddWithTwoOperands", ReplyAction="http://tempuri.org/ICalculator/AddWithTwoOperandsResponse")]
        
double AddWithTwoOperands(double x, double y);
        
        [System.ServiceModel.OperationContractAttribute(Action
="http://tempuri.org/ICalculator/AddWithThreeOperands", ReplyAction="http://tempuri.org/ICalculator/AddWithThreeOperandsResponse")]
        
double AddWithThreeOperands(double x, double y, double z);
    }

    
    [System.CodeDom.Compiler.GeneratedCodeAttribute(
"System.ServiceModel""3.0.0.0")]
    
public interface ICalculatorChannel : Artech.OverloadableContract.Client.CalculatorService.ICalculator, System.ServiceModel.IClientChannel
    
{
}

我們可以看到這個Service Contract已經(jīng)不是Service端的Contract了,Overloading方法已經(jīng)被換成了與Oper阿tion Name相匹配的方法了。我們再看看Proxy Class:

[System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute(
"System.ServiceModel""3.0.0.0")]
    
public partial class CalculatorClient : System.ServiceModel.ClientBase<Artech.OverloadableContract.Client.CalculatorService.ICalculator>, Artech.OverloadableContract.Client.CalculatorService.ICalculator
    
{
        
        
public CalculatorClient()
        
{
        }

        
        
public CalculatorClient(string endpointConfigurationName) : 
                
base(endpointConfigurationName)
        
{
        }

        
        
public CalculatorClient(string endpointConfigurationName, string remoteAddress) : 
                
base(endpointConfigurationName, remoteAddress)
        
{
        }

        
        
public CalculatorClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
                
base(endpointConfigurationName, remoteAddress)
        
{
        }

        
        
public CalculatorClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
                
base(binding, remoteAddress)
        
{
        }

        
        
public double AddWithTwoOperands(double x, double y)
        
{
            
return base.Channel.AddWithTwoOperands(x, y);
        }

        
        
public double AddWithThreeOperands(double x, double y, double z)
        
{
            
return base.Channel.AddWithThreeOperands(x, y, z);
        }

}

實現(xiàn)了我們倒入的Service Contract并提供了相應(yīng)的Constract,相關(guān)的也在前面的Blog提及,這里不用再多說什么了。現(xiàn)在我們毫無疑問,可以直接調(diào)用非重載的方法AddWithTwoOperands和AddWithThreeOperands來調(diào)用Calculator Service。但是我們需要的不是這樣,我們需要的Overloading,在Service 我們實現(xiàn)以O(shè)verlaoding的方式提供Service,在Client端我們也希望以相同的方式來調(diào)用這個Service。下面我們來看怎么做:

在Client端,重寫Service Contract,當然是一Overloading的方式,同時像在Service端一樣,通過OperatonContract的Name屬性為Operation 制定一個和Service完全匹配的Operation Name。

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;

namespace Artech.OverloadableContract.Client
{
    [ServiceContract(Name 
= "ICalculator")]
   
public interface IMyCalculator
    
{
        [OperationContract(Name 
= "AddWithTwoOperands")]
       
double Add(double x, double y);

       [OperationContract(Name 
= "AddWithThreeOperands")]
       
double Add(double x, double y, double z);
    }

}

重寫Proxy Class

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;

namespace Artech.OverloadableContract.Client
{
    
class MyCalculatorClient:ClientBase<IMyCalculator>,IMyCalculator
    
{
        
IMyCalculator Members
    }

}

現(xiàn)在我們有兩個Proxy Class,我們同時使用,看看他們會不會返回一樣的結(jié)果:

using System;
using System.Collections.Generic;
using System.Text;
using Artech.OverloadableContract.Client.CalculatorService;

namespace Artech.OverloadableContract.Client
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            Console.WriteLine(
"Begin to invocate generated proxy");
            InvocateGeneratedProxy();
            Console.WriteLine(
"\nBegin to invocate revised proxy");
            InvocateGeneratedProxy();
Console.Read();
        }


        
static void InvocateGeneratedProxy()
        
{
            
using (CalculatorClient calculator = new CalculatorClient())
            

                Console.WriteLine(
"x + y = {2} where x = {0}and y = {1} ",1,2,calculator.AddWithTwoOperands(1,2));
                Console.WriteLine(
"x + y + z = {3} where x = {0}and y = {1} and z = {2}"123,calculator.AddWithThreeOperands(12,3));
            }

        }


        
static void InvocateRevisedProxy()
        
{
            
using (MyCalculatorClient calculator = new MyCalculatorClient())
            
{
                Console.WriteLine(
"x + y = {2} where x = {0}and y = {1} "12, calculator.Add(12));
                Console.WriteLine(
"x + y + z = {3} where x = {0}and y = {1} and z = {2}"123, calculator.Add(123));
            }

        }

    }

}

同時在加入下面簡單的Configuration:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    
<system.serviceModel>
        
<client>
            
<endpoint address="http://localhost:1234/calcuator" binding="basicHttpBinding"                 contract="Artech.OverloadableContract.Client.IMyCalculator" />
                  
</client>
    
</system.serviceModel>
</configuration>

 

運行Client,下面是Screen Shot,可見兩個Proxy是等效的。


本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
如何實現(xiàn)Service Contract的重載(Overloading)
我的WCF之旅(1):創(chuàng)建一個簡單的WCF程序
我的WCF之旅(3):在WCF中實現(xiàn)雙工通信
一個通過JSONP跨域調(diào)用WCF REST服務(wù)的例子(以jQuery為例)
[WCF 4.0新特性] 標準終結(jié)點與無(.SVC)文件服務(wù)激活
MSDN上的WCF入門教程
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服