自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MRS實現(xiàn)和擴展一個Service Contract

開發(fā) 后端
這篇文章描述了使用三種方法來實現(xiàn)或擴展一個通用服務(wù)協(xié)議(generic service contract),其中包括實現(xiàn)一個通用服務(wù)協(xié)議、擴展一個服務(wù)協(xié)議以及多頭服務(wù)(Multi-Headed Service),這個實例中使用的通用的服務(wù)協(xié)議是在Service Tutorial 8 (C#) - Generic Service Declaration.所創(chuàng)建的。

這個實例由實現(xiàn),可以在下面的目錄中找到這個項目:

Samples"ServiceTutorials"Tutorial9"CSharp

創(chuàng)建項目

由于項目需要擴展一個通用服務(wù)協(xié)議(generic service contract),所以項目中需要引用Service Tutorial 8項目生成的dll文件,在Service Tutorial 9項目你會看到它實現(xiàn)了三個個服務(wù),在一個項目中實現(xiàn)多個服務(wù)的話,要確保這些服務(wù)的命名空間是不同的哦。

第二步:實現(xiàn)一個通用服務(wù)協(xié)議

第一個服務(wù)實例是GenericServiceImplementation,實現(xiàn)這個服務(wù)的文件是GenericServiceImplementation.csGenericServiceImplementationTypes.cs,這個服務(wù)僅僅是實現(xiàn)了一個通用服務(wù)協(xié)議。

服務(wù)類型聲明(Service Type Declarations):

因為在這個服務(wù)中使用了通用服務(wù)協(xié)議,因此它不需要我們?nèi)ザx他的狀態(tài)和操作,這些在通用服務(wù)協(xié)議已經(jīng)定義好了,看看ServiceTutorial8就知道了,但是它還是需要一個協(xié)議標識(Contract identifier),因為需要用這個標識來找到這個服務(wù),服務(wù)標識定義如下:

 1 /// 
 2 /// Generic Service Implementation Contract Identifier
 3 /// 

 4 public sealed class Contract
 5 
 6 {
 7     /// The Unique Contract Identifier for this service
 8 
 9     [DataMember()]
10     public const String Identifier = "http://schemas.tempuri.org/2007/08/servicetutorial9/genericservice/implementation.html";
11 }
12 

引用通用協(xié)議(Referencing the Generic Contract  

在項目中引用通用服務(wù)協(xié)議代理程序集(generic contract's proxy assembly),一定要引用代理程序集,即*Proxy.dll,這個文件可以在msrs安裝根目錄下的bin文件夾中找到,為這個通用服務(wù)協(xié)議的命名空間定義一個別名,如下:

using generic = ServiceTutorial8.Proxy;

服務(wù)實現(xiàn)

這個服務(wù)的實現(xiàn)和其他的服務(wù)基本沒有什么區(qū)別,有兩點如下:

1、 服務(wù)實現(xiàn)類需要用AlternateContract屬性標記,用來指示在這個服務(wù)中使用的是通用服務(wù)協(xié)議。

 1 /// 
 2 /// This service provides an implementation of the generic service
 3 /// 

 4 [Contract(Contract.Identifier)]
 5 [AlternateContract(generic.Contract.Identifier)]
 6 [DisplayName("Service Tutorial 9: Generic Service Implementation")]
 7 [Description("This service implements the generic service provided in Service Tutorial 8.")]
 8 [DssServiceDescription("http://msdn.microsoft.com/library/bb727257.aspx")]
 9 public class ImplementationService : DsspServiceBase
10 

2、 因為這個服務(wù)自己沒有定義狀態(tài)和操作,狀態(tài)和操作都在通用服務(wù)協(xié)議有所定義了,只需在服務(wù)中使用罷了。如下:

 1 // The state of this service is exactly that of the generic service
 2 [ServiceState]
 3 private generic.GenericState _state = new generic.GenericState();
 4 
 5 // The operations port is exactly that of the generic service
 6 [ServicePort("/GenericServiceImplementation", AllowMultipleInstances = false)]
 7 private generic.GenericServiceOperations _mainPort = new generic.GenericServiceOperations();
 8 
 9 /// 
10 /// Default Service Constructor
11 /// 

12 public ImplementationService(DsspServiceCreationPort creationPort)
13     :
14         base(creationPort)
15 {
16 }
17 

剩下的工作是為通用協(xié)議中的定義的消息操作(message operations)添加處理方法(handler),如下代碼定義了Get操作的處理方法:

1         /// Get Handler
 2         /// 
 3         /// 
 4         /// 
 5         // Note that this service does not need to implement Get unless there are
 6         // some specific functions that it must perform
 7         [ServiceHandler(ServiceHandlerBehavior.Concurrent)]
 8 
 9         public virtual IEnumerator<ITask> GetHandler(generic.Get get)
10         {
11             get.ResponsePort.Post(_state);
12             yield break;
13         }
14 

 

運行服務(wù)

運行服務(wù)后,在瀏覽器中Service Directory可以查看到兩個服務(wù)genericserviceimplementationgenericserviceimplementation/servicetutorial8.因為服務(wù)沒有擴展通用服務(wù)協(xié)議,所以這兩個服務(wù)的狀態(tài)和操作是一樣的。

圖1,運行服務(wù),如圖紅框標出DSS節(jié)點中運行了兩個服務(wù)(genericserviceimplementation and genericserviceimplementation/servicetutorial8),兩個服務(wù)有相同的狀態(tài)和操作類型。

第三步:擴展一個通用服務(wù)協(xié)議

第二個服務(wù)提供了對通用服務(wù)協(xié)議的實現(xiàn),同時又添加了一個自己的狀態(tài)和消息操作,這樣做的目的是:如果服務(wù)使用者只知道通用服務(wù)協(xié)議所定義狀態(tài)和操作的話,他可以很容易使用這個服務(wù),并且,這個服務(wù)還允許使用者使用擴展的狀態(tài)和操作。

服務(wù)類型聲明

和前面實現(xiàn)的服務(wù)不同,前面的服務(wù)沒有自己的服務(wù)類型聲明,而這個服務(wù)有自己服務(wù)類型聲明,包括協(xié)議標識,服務(wù)狀態(tài)以及服務(wù)操作,其中服務(wù)狀態(tài)繼承自通用服務(wù)中的狀態(tài)。

協(xié)議標識聲明如下:

1 /// 
2 /// Generic Service Extension Contract Identifier
3 /// /// 

4 public static class Contract
5 {
6     public const string Identifier = "http://schemas.tempuri.org/2007/08/servicetutorial9/genericservice/extension.html";
7 }

其中的服務(wù)狀態(tài)繼承自通用服務(wù)協(xié)議中的狀態(tài),同時有所擴展,添加了Age屬性,繼承實現(xiàn)如下:

1 [DataContract]
 2 [DisplayName("Service Tutorial 9: Extension Service State")]
 3 [Description("This service state extends the generic service state provided in Service Tutorial 8.")]
 4 public class ExtensionState : generic.GenericState
 5 {
 6     int _age; 
 7     [DataMember]
 8     [DisplayName("Age")]
 9     [Description("Specifies the age of a person.")]
10     public int Age
11     {
12         get { return _age; }
13         set { _age = value; }
14     }
15  
16 

除了添加了新的屬性,又添加了構(gòu)造函數(shù),這個構(gòu)造函數(shù)通過一個基類的實例來初始化子類對象,
更有意思的是,又添加了個類型轉(zhuǎn)換方法,這個方法將子類轉(zhuǎn)換為父類,這樣做的原因是,
有時候我們想獲得一個通用服務(wù)協(xié)議中定義的狀態(tài)對象的序列化對象,而不包括子類所擴展的其他信息,
假如僅僅使用CLR所默認的隱式類型轉(zhuǎn)換,我們得到的對象仍舊是子類對象,因此,要獲得一個基類型的序列化對象,
只能顯示的實現(xiàn)一個基類對象,而不是隱式轉(zhuǎn)換。

 1 internal ExtensionState(generic.GenericState state)
 2 {
 3     this.FirstName = state.FirstName;
 4     this.LastName = state.LastName;
 5     this.Age = -1;
 6 }
 7 internal generic.GenericState ToGenericState()
 8 {
 9 
10     generic.GenericState gen = new generic.GenericState();
11     gen.FirstName = this.FirstName;
12     gen.LastName = this.LastName;
13     return gen;
14 }
15 
16 

這個實例中我們又添加了一個消息操作類型,即UpdateAge操作,假如我們沒有擴展服務(wù)狀態(tài)而只是添加一個操作,我們可以重用通用服務(wù)協(xié)議定義的消息操作類,但是這里我們只能重新定義一個服務(wù)操作。

 1 /// 
 2 /// Generic Service Extension Main Operations Port
 3 /// 

 4 [ServicePort]
 5 public class GenericServiceExtensionOperations :
 6 
 7     PortSet<DsspDefaultLookup, DsspDefaultDrop, Get, Replace, UpdateAge>
 8 {
 9 
10 }
11 

服務(wù)實現(xiàn)

和前面的服務(wù)的實現(xiàn)方式不一樣,前面服務(wù)完全使用通用服務(wù)的協(xié)議中定義的狀態(tài)和操作,而這個服務(wù)的狀態(tài)和主端口都使用的擴展的狀態(tài)和操作,因為主端口使用的是擴展的操作類型,所以它并不能處理從備用端口傳來的消息,因此,和前面服務(wù)不同的是,我們還需要聲明另一個端口用來處理通用服務(wù)協(xié)議中定義的操作,這個端口即備用端口(AlternateServicePort),在對端口的聲明上和前面的服務(wù)有所不同,前面的服務(wù)在類(ExtensionService層次上使用AlternateContract屬性,這里我們用AlternateServicePort屬性來標記備用端口,代碼如下:

 

 1 // The state of this service is an extension of the generic service
 2 private ExtensionState _state = new ExtensionState();
 3  
 4 // The operations port is an extension of the generic service in that it supports UPDATE as well
 5 [ServicePort("/GenericServiceExtension", AllowMultipleInstances = false)]
 6 private GenericServiceExtensionOperations _mainPort = new GenericServiceExtensionOperations();
 7  
 8 // The alternate port where we only have the generic service operations (without UPDATE)
 9 [AlternateServicePort(AlternateContract = generic.Contract.Identifier)]
10 private generic.GenericServiceOperations _altPort = new generic.GenericServiceOperations();
11 

注意:

AlternateContractAlternateServicePort是不能同時使用的哦,當你將通用服務(wù)協(xié)議所定義的操作類用作主端口時,那么使用AlternateContract屬性來標記這個服務(wù),而如果你沒有將通用服務(wù)協(xié)議定義的操作類作為主端口,而是將它作為備用端口,那就要在端口聲明時為其標記AlternateServicePort屬性。

 

剩下的事就是為消息定義處理方法,因為這個服務(wù)中有兩個端口,每個端口都有自己的消息類型,即主端口和備用端口各自接收自己所定義的消息,代碼如下:

這段是處理主端口傳來的消息:

 

 1 /// 
 2 /// Get Handler
 3 /// 

 4 /// 
 5 /// 
 6 [ServiceHandler(ServiceHandlerBehavior.Concurrent)]
 7 
 8 public virtual IEnumerator<ITask> GetHandler(Get get)
 9 
10 {
11     get.ResponsePort.Post(_state);
12     yield break;
13 
14 }
15 
16  
17 
18 /// 
19 /// Replace Handler
20 /// 

21 /// 
22 /// 
23 [ServiceHandler(ServiceHandlerBehavior.Exclusive)]
24 public virtual IEnumerator<ITask> ReplaceHandler(Replace replace)
25 
26 {
27 
28     _state = replace.Body;
29     replace.ResponsePort.Post(DefaultReplaceResponseType.Instance);
30     yield break;
31 
32 }
33 
34  
35 
36 /// 
37 /// Update Handler
38 /// 

39 /// 
40 /// 
41 [ServiceHandler(ServiceHandlerBehavior.Exclusive)]
42 
43 public virtual IEnumerator<ITask> UpdateAgeHandler(UpdateAge update)
44 
45 {
46 
47     _state.Age = update.Body.Age;
48     update.ResponsePort.Post(DefaultUpdateResponseType.Instance);
49     yield break;
50 
51 }
52 
53  
54 
55 

 

這段是處理從備用端口傳來的消息的代碼,這里使用了服務(wù)狀態(tài)中所定義的類型轉(zhuǎn)換方法ToGenericState,從子類對象中抽離出了父類對象,這樣的好處是,提高了這個服務(wù)的通用性,因為父類對象是在通用服務(wù)協(xié)議中定義的,是大家所共知的,是規(guī)范,和其他服務(wù)交互的時候通常是傳遞的這個通用的狀態(tài)對象的哦,彼此之間耦合就降了下來,這和面向?qū)ο笾械亩鄳B(tài)類似哦。

同時要注意這些處理方法的屬性中多了一個參數(shù)PortFieldName,這個參數(shù)用來告訴DSS運行時環(huán)境將這個處理方法附加到名字為_altPort的備用端口(Alternate Port)上。

沒有使用這個參數(shù)的處理方法會被DSS環(huán)境會附加到主端口(Service Port)。

/// 
/// Get Handler
/// 

/// 
/// 

[ServiceHandler(ServiceHandlerBehavior.Concurrent, PortFieldName = "_altPort")]

public virtual IEnumerator<ITask> GenericGetHandler(generic.Get get)

{

   get.ResponsePort.Post(_state.ToGenericState());
    yield break;

}

 

/// 
/// Replace Handler
/// 

/// 
/// 
[ServiceHandler(ServiceHandlerBehavior.Exclusive, PortFieldName = "_altPort")]

public virtual IEnumerator<ITask> GenericReplaceHandler(generic.Replace replace)

{

    _state = new ExtensionState(replace.Body);
    replace.ResponsePort.Post(DefaultReplaceResponseType.Instance);
    yield break;

}

運行服務(wù)

運行服務(wù)后,從服務(wù)目錄同樣可以看到兩個服務(wù)(genericserviceextension and genericserviceextension/servicetutorial8),但是和前面實現(xiàn)通用協(xié)議的服務(wù)不同,這兩個服務(wù)有不同的狀態(tài)。

圖2-運行服務(wù)后在目錄中出現(xiàn)兩個服務(wù)(genericserviceextension and genericserviceextension/servicetutorial8)這兩個服有不同的狀態(tài)和操作,包括相同的狀態(tài)實例。

第一個服務(wù)(genericserviceextension)包含了擴展的狀態(tài)和操作,第二個服務(wù)(genericserviceextension/servicetutorial8)包含通用的狀態(tài)和操作。

圖3-第二個服務(wù)(genericserviceextension/servicetutorial8)包含通用的狀態(tài)和操作,這樣其他的服務(wù)可以把這個服務(wù)視為通用服務(wù)而與之通信了。

第四步:實現(xiàn)一個多例服務(wù)(multi-headed service

最后一個服務(wù)實例在(MultiFunctionService.cs and MultiFunctionServiceTypes.cs)定義,MSDN中稱它為(multi-headed service),我們稱他為多例服務(wù),即在一個服務(wù)中實現(xiàn)多個狀態(tài)和端口,端口之間是相互獨立并行執(zhí)行,就好像一個服務(wù)中包含了多個獨立的服務(wù)實例,從外部看來,這些服務(wù)都是相互獨立的,他們可能共享了一個資源或者相互之間有比較高的耦合度,當開發(fā)多例服務(wù)時,還是需要考慮下把這些服務(wù)分開來實現(xiàn)是不是更好呢?因為分開實現(xiàn)會有更大的靈活性。

多例服務(wù)的實現(xiàn)和前面所說的服務(wù)實現(xiàn)方法是一樣的,他可能會有多個操作端口,一個主端口(main port),其他的是備用端口(alternate port),并且還要為這些端口分別實現(xiàn)消息處理方法。

和前面服務(wù)不同的是,多例服務(wù)包括多個狀態(tài)對象實例,這些狀態(tài)實例看起來并不相關(guān)。  

 1 // The first state of this multi headed service
 2 private AddressState _address = new AddressState();
 3 
 4 // The operations port used for the first service
 5 [ServicePort("/AddressService", AllowMultipleInstances = false)]
 6 private AddressServiceOperations _mainPort = new AddressServiceOperations();
 7 
 8 // The second state of this multi headed service
 9 private generic.GenericState _name = new generic.GenericState();
10 
11 // The alternate port used for the second service
12 [AlternateServicePort(AlternateContract = generic.Contract.Identifier)]
13 private generic.GenericServiceOperations _altPort = new generic.GenericServiceOperations();
14 

對每個端口分別實現(xiàn)消息處理方法,每個端口的處理方法各自維護自己的狀態(tài)對象。

 1 // Service handlers for service one
 2 
 3 /// 
 4 /// Get Handler
 5 /// 

 6 /// 
 7 /// 
 8 [ServiceHandler(ServiceHandlerBehavior.Concurrent)]
 9 public virtual IEnumerator<ITask> GetAddressHandler(Get get)
10 {
11     get.ResponsePort.Post(_address);
12     yield break;
13 }
14 
15 /// 
16 /// Replace Handler
17 /// 

18 /// 
19 /// 
20 [ServiceHandler(ServiceHandlerBehavior.Exclusive)]
21 public virtual IEnumerator<ITask> ReplaceAddressHandler(Replace replace)
22 {
23     _address = replace.Body;
24     replace.ResponsePort.Post(DefaultReplaceResponseType.Instance);
25     yield break;
26 }
27 
28 // Service handlers for service two
29 
30 /// 
31 /// Get Handler
32 /// 

33 /// 
34 /// 
35 [ServiceHandler(ServiceHandlerBehavior.Concurrent, PortFieldName = "_altPort")]
36 public virtual IEnumerator<ITask> GetNameHandler(generic.Get get)
37 {
38     get.ResponsePort.Post(_name);
39     yield break;
40 }
41 
42 /// 
43 /// Replace Handler
44 /// 

45 /// 
46 /// 
47 [ServiceHandler(ServiceHandlerBehavior.Exclusive, PortFieldName = "_altPort")]
48 public virtual IEnumerator<ITask> ReplaceNameHandler(generic.Replace replace)
49 {
50     _name = replace.Body;
51     replace.ResponsePort.Post(DefaultReplaceResponseType.Instance);
52     yield break;
53 }

 

運行服務(wù)

運行服務(wù)后,服務(wù)列表中顯示兩個實例(addressservice and addressservice/servicetutorial8.)但是,兩個服務(wù)實例的返回狀態(tài)是不同的。

這是MRDS的服務(wù)實例中的第九個,講的的是如何實行或擴展一個通用服務(wù)協(xié)議,在實際應(yīng)用中是很有用的,因為我們不必自己定義通信的消息類型和操作類型了,直接使用微軟自己定義的協(xié)議,這樣這些服務(wù)在VPL里就可以變得通用了,微軟自己定義了一套協(xié)議,呼呼,他希望大家都去實現(xiàn),微軟眼光很長遠,想在機器人領(lǐng)域續(xù)寫PC領(lǐng)域的輝煌哦……

【編輯推薦】

  1. 微軟MVP初探WF 4.0 beta1 嶄新面貌讓人吃驚
  2. 微軟發(fā)布Visual Studio 2010 Beta 1
  3. 微軟發(fā)布托管服務(wù)引擎MSE新版本
責任編輯:彭凡 來源: cnblogs
相關(guān)推薦

2020-03-18 15:00:37

BasiliskFirefox瀏覽器

2016-01-06 09:57:23

編寫PHP擴展

2024-11-20 13:18:21

2023-02-01 16:36:31

GNOMEChatGPTLinux

2019-06-05 13:05:47

PHP語法糖編碼

2023-01-02 18:15:42

PythonC++模塊

2009-08-10 10:08:45

.NET調(diào)用PHP W

2015-07-28 14:35:40

2025-01-21 08:11:24

2020-09-24 11:46:03

Promise

2022-08-02 14:21:20

滑動驗證碼鴻蒙

2022-07-13 15:31:29

手繪板canvas鴻蒙

2022-01-04 11:08:02

實現(xiàn)Localcache存儲

2022-07-28 14:20:44

懸浮球鴻蒙

2017-12-12 15:24:32

Web Server單線程實現(xiàn)

2014-04-14 15:54:00

print()Web服務(wù)器

2017-10-18 15:28:08

Service WorPWA離線

2015-12-02 11:23:38

DockerUber容器服務(wù)

2023-05-22 09:10:53

CSSloading 效

2011-03-28 09:56:03

存儲增刪操作
點贊
收藏

51CTO技術(shù)棧公眾號