首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Microsoft Robotics Studio 開發指南:實作與擴展通用服務合約

     編輯:關於.NET

Microsoft Robotics Developer Studio (MRDS) 採用 DSS (Decentralized Software Services) 架構,服務間透過通用服務合約 實現互通。本文基於 Service Tutorial 9 (C#),詳細說明三種實作策略:直接實作、擴展合約、多頭服務,並附完整程式碼關鍵點解析。

專案結構與前置作業

  • 專案位置:Samples\ServiceTutorials\Tutorial9\CSharp
  • 參考 Service Tutorial 8 產生的 *Proxy.dll (位於 MRDS 安裝目錄 bin),定義通用合約:GenericState、GenericServiceOperations、Contract.Identifier。
  • 單一專案實作多個服務時,務必使用不同命名空間隔離。

策略一:直接實作通用合約

服務名:GenericServiceImplementation。不定義自身狀態與操作,完全委派給通用合約。

關鍵程式碼要點

  1. 合約識別碼:自訂唯一 URI。
    public sealed class Contract {
        public const String Identifier = "https://schemas.tempuri.org/2007/08/servicetutorial9/genericservice/implementation.html";
    }
    
  2. 引用通用合約 Proxy:using generic = ServiceTutorial8.Proxy;
  3. 服務類別標記:
    [Contract(Contract.Identifier)]
    [AlternateContract(generic.Contract.Identifier)]  // 宣告支援通用合約
    [DisplayName(...)]
    [Description(...)]
    public class ImplementationService : DsspServiceBase
    
  4. 狀態與主連接埠直接使用通用型別:
    [ServiceState] private generic.GenericState _state = new generic.GenericState();
    [ServicePort("/GenericServiceImplementation", AllowMultipleInstances = false)]
    private generic.GenericServiceOperations _mainPort = new generic.GenericServiceOperations();
    
  5. 處理器只需實作通用操作 (Get、Replace 等):
    [ServiceHandler(ServiceHandlerBehavior.Concurrent)]
    public virtual IEnumerator GetHandler(generic.Get get) {
        get.ResponsePort.Post(_state);
        yield break;
    }
    

執行結果

服務目錄顯示兩個服務節點:genericserviceimplementation 與 genericserviceimplementation/servicetutorial8,**狀態與操作完全相同**,後者為通用合約的標準投影。

策略二:擴展通用合約

服務名:GenericServiceExtension。保留通用合約功能,同時新增自有狀態 (Age) 與操作 (UpdateAge),實現向後相容與功能擴展並存。

關鍵差異點

  1. 自有合約識別碼:不同於通用合約 URI。
  2. 狀態繼承與擴展:
    [DataContract]
    public class ExtensionState : generic.GenericState {
        private int _age;
        [DataMember] public int Age { get { return _age; } set { _age = value; } }
    
        // 從基底狀態建構 (用於 Replace 通用操作)
        internal ExtensionState(generic.GenericState state) {
            this.FirstName = state.FirstName;
            this.LastName = state.LastName;
            this.Age = -1;
        }
        // 顯式轉換為基底狀態 (用於 Get 通用操作回傳)
        internal generic.GenericState ToGenericState() {
            var gen = new generic.GenericState();
            gen.FirstName = this.FirstName;
            gen.LastName = this.LastName;
            return gen;
        }
    }
    
  3. 操作連接埠擴展:新增 UpdateAge 至 PortSet。
    [ServicePort]
    public class GenericServiceExtensionOperations : PortSet { }
    
  4. 雙連接埠架構:主連接埠用擴展操作,備用連接埠 (AlternateServicePort) 掛載通用操作。
    
    // 主連接埠 (擴展)
    [ServicePort("/GenericServiceExtension", AllowMultipleInstances = false)]
    private GenericServiceExtensionOperations _mainPort = new GenericServiceExtensionOperations();
    
    // 備用連接埠 (通用)
    [AlternateServicePort(AlternateContract = generic.Contract.Identifier)]
    private generic.GenericServiceOperations _altPort = new generic.GenericServiceOperations();
    
    注意:AlternateContract (用於類別) 與 AlternateServicePort (用於連接埠) **不可同時使用**。若主連接埠即為通用操作,用前者;若主連接埠為擴展操作,通用操作置於備用連接埠,用後者。
  5. 處理器對應連接埠:主連接埠處理器無特殊標記;備用連接埠處理器需標記 PortFieldName = "_altPort"。
    [ServiceHandler(ServiceHandlerBehavior.Concurrent, PortFieldName = "_altPort")]
    public virtual IEnumerator GenericGetHandler(generic.Get get) {
        get.ResponsePort.Post(_state.ToGenericState()); // 回傳基底狀態
        yield break;
    }
    

執行結果

服務目錄顯示 genericserviceextension (含 Age 與 UpdateAge) 與 genericserviceextension/servicetutorial8 (僅通用狀態與操作) **狀態結構不同**,後者可被僅知通用合約的消費者透明使用。

策略三:多頭服務

服務名:MultiFunctionService。單一服務進程內承載多個獨立狀態與連接埠 (AddressService + 通用 NameService),外觀上如同多個獨立服務,內部可共享資源或高耦合邏輯。

實作要點

// 狀態 1 + 主連接埠
private AddressState _address = new AddressState();
[ServicePort("/AddressService", AllowMultipleInstances = false)]
private AddressServiceOperations _mainPort = new AddressServiceOperations();

// 狀態 2 + 備用連接埠 (通用合約)
private generic.GenericState _name = new generic.GenericState();
[AlternateServicePort(AlternateContract = generic.Contract.Identifier)]
private generic.GenericServiceOperations _altPort = new generic.GenericServiceOperations();

各連接埠對應獨立處理器 (GetAddressHandler/ReplaceAddressHandler、GetNameHandler/ReplaceNameHandler),各自維護自己的狀態實例。服務目錄顯示 addressservice 與 addressservice/servicetutorial8,**回傳狀態型別不同**。

架構選擇建議

策略適用場景耦合度彈性
直接實作需完全符合標準合約,無額外功能低 (僅依賴合約)低
擴展合約需相容現有消費者,同時提供新功能中 (基底合約穩定)高
多頭服務多個緊密相關功能需共享進程/資源高 (內部耦合)中 (建議評估拆分為獨立服務)

MRDS 定義通用合約旨在建立機器人服務生態標準,透過 VPL (Visual Programming Language) 實現拖曳式組合。掌握三種實作模式,是開發可互操作機器人服務的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved