<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      我的WCF之旅(5):面向服務架構(SOA)和面向對象編程(OOP)的結合——如何實現Service Contract的重載(Overloading)

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

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

      而對于XML Web Service,它的標準實際上是基于XML的,近一步說,一個XML Web Service是通過一個一段XML來描述的,而這個描述XML Web Service的XML,我們稱之為WSDL(Web Service Description Language)。在WSDL中,Web Service的一個方法(Method)對應的是一個操作(Operation),Web Service 所有的Operation定義在WSDL中的portType Section。我們可以參照下面一段XML,它是從一個完整的WSDL中截取下來的。我們可以看到,portType包含了Web Service定義的所有Operation,每個Operation由一個operation XML Element表示。看過我前面Blog的讀者應該知道,從消息交換(Message Exchange)的層面上講,一個Operation實際上體現的是一種消息交換的模式(Message Exchange Pattern——MEP)。所以我們完全可以通過一定消息交換的輸入消息(Input Message)和輸出(Output Message )定義一個Operation。而WSDL也是這樣做的。(這里順便提一下,Output Message部僅僅對應一個方法的Return Value,還包括表明ref 和out的Parameter)。除了定義進行消息交互的Message的格式(一般通過XSD)之外,每個Operation還應該具有一個能夠為一標識該Operation的ID,這個ID通過name XML Attribute來定義。通常的情況下,Operation的Name使用Web Service的方法名——這就是在傳統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。雖然現有XML Web Service現在具有廣泛的使用——尤其在構建跨平臺性的分布是應用和進行系統集成上面,但是從Microsoft已經明確提出WSE 3.0將是最后一個Version的WSE,所以,現有的Web Service將會全面的過渡到WCF。WCF到底是什么東西,我在前面的文章中不斷地提出這個問題,在這里我們從 另外一個方面來看待WCF。我們知道W3C定義了一系列關于WS的規范Specification,成為WS-* Specification。這一系列的Specification定義了建立在XML和SOAP標準之上的基于如何將一個可互操作系統(Interoperable System)的各個方面的標準,比如WS-Messaging,WS-Security,WS-Transaction等等。而WCF則可以看成是這一整套Specification的實現。但是這種實現最終還是落實到我們.NET編程上。我們可以把WS-Specification和我們的基于.NET語言的編程看成是兩種截然不同的編程模型(Programming Model)。WCF的功能則是把這兩種不同的編程模型統一起來,實現他們之間的一個Mapping——可以把WCF看成一個Adapter。

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

      沿用我們的Calculator的應用,現在我們做一個加法器,它具有兩個Operation——兩書相加和三數相加。這兩個方法都用一個名稱Add。

      1.下面是Solution的結構。不像前面的結構,這這里我們沒有把Service Contract單獨提取出來,供Client和Service供用。因為我們現在模擬的是,Service完全由一個外部的第三方提供,Service 已經確定,不能根據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,簡單地實現了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();
                  }

              }

          }

      }

      相關的已經在前面的文章中說過,代碼很簡單,沒有什么好說的。

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

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


      4.接下來我們為Client端添加一個Server Reference。就像在使用XML Web Service中添加Web Reference一樣,添加Server Reference會為Client添加相應的客戶端代碼——倒入的Service Contract,繼承自ClientBase<T>的Proxy Class, 和相應的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已經不是Service端的Contract了,Overloading方法已經被換成了與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);
              }

      }

      實現了我們倒入的Service Contract并提供了相應的Constract,相關的也在前面的Blog提及,這里不用再多說什么了。現在我們毫無疑問,可以直接調用非重載的方法AddWithTwoOperands和AddWithThreeOperands來調用Calculator Service。但是我們需要的不是這樣,我們需要的Overloading,在Service 我們實現以Overlaoding的方式提供Service,在Client端我們也希望以相同的方式來調用這個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
          }

      }

      現在我們有兩個Proxy Class,我們同時使用,看看他們會不會返回一樣的結果:

      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是等效的。



      WCF相關內容:
      [原創]我的WCF之旅(1):創建一個簡單的WCF程序
      [原創]我的WCF之旅(2):Endpoint Overview
      [原創]我的WCF之旅(3):在WCF中實現雙向通信(Bi-directional Communication)
      [原創]我的WCF之旅(4):WCF中的序列化(Serialization)- Part I
      [原創]我的WCF之旅(4):WCF中的序列化(Serialization)- Part II
      [原創]我的WCF之旅(5):Service Contract中的重載(Overloading)
      [原創]我的WCF之旅(6):在Winform Application中調用Duplex Service出現TimeoutException的原因和解決方案
      [原創]我的WCF之旅(7):面向服務架構(SOA)和面向對象編程(OOP)的結合——如何實現Service Contract的繼承
      [原創]我的WCF之旅(8):WCF中的Session和Instancing Management
      [原創]我的WCF之旅(9):如何在WCF中使用tcpTrace來進行Soap Trace
      [原創]我的WCF之旅(10): 如何在WCF進行Exception Handling
      [原創]我的WCF之旅(11):再談WCF的雙向通訊-基于Http的雙向通訊 V.S. 基于TCP的雙向通訊

      [原創]我的WCF之旅(12):使用MSMQ進行Reliable Messaging
      [原創]我的WCF之旅(13):創建基于MSMQ的Responsive Service

      posted @ 2007-03-19 02:25  Artech  閱讀(31444)  評論(42)    收藏  舉報
      主站蜘蛛池模板: 无码人妻久久久一区二区三区| 亚洲sm另类一区二区三区| 亚洲午夜精品久久久久久抢| 国产精品亚洲综合色区丝瓜| 色婷婷狠狠久久综合五月| 97se亚洲国产综合自在线观看| 好男人社区在线www| 午夜射精日本三级| 免费无码va一区二区三区 | 99在线精品国自产拍中文字幕| 亚洲国产精品综合久久2007| 成人免费A级毛片无码网站入口| 国产午夜精品久久久久免费视| 国产69精品久久久久久| aaa少妇高潮大片免费看| 麻豆亚洲自偷拍精品日韩另| 久久久久香蕉国产线看观看伊| 国产午夜A理论毛片| 苍井空一区二区三区在线观看| 国产精品乱码人妻一区二区三区| 中文字幕人妻中出制服诱惑| 99国产精品久久久久久久日本竹| 人妻少妇偷人精品免费看| 不卡一区二区国产精品| 免费人成网站视频在线观看| 亚洲高清有码中文字| 欧美人与动zozo在线播放| 99www久久综合久久爱com| 利辛县| 加勒比无码人妻东京热| 国产老头多毛Gay老年男| 亚洲综合色区另类av| 手机看片福利一区二区三区 | 中国凸偷窥xxxx自由视频| 国产日韩入口一区二区| 超碰伊人久久大香线蕉综合| 野外少妇被弄到喷水在线观看 | 黑人异族巨大巨大巨粗| 婷婷四虎东京热无码群交双飞视频| 亚洲一区无码精品色| av午夜福利一片看久久|