2012-03-12 52 views
2

我在尋找實施智能體系結構的良好實踐和處理與具有許多不同wdsl web服務的系統的集成的方法。關於消耗/包裝大型web服務的體系結構技巧

我一直在用C#開發2年的愛好〜,因爲我並不總是使用正確的術語,但我會盡力描述我在尋找的東西。

我發佈這篇文章的主要原因是想了解我應該閱讀的領域,實現設計模式以及如何以良好的方式管理API調用。

我正在整合一個提供大量不同API的系統。每個API都有20-30個方法。每個API都採用XML格式的許多參數。

爲了給你一個想法,我以下面的API爲例,它的DeviceManager API和Create方法在系統中創建一個設備。 API接受兩個參數,一個字符串鍵和一個XML參數字符串。

DeviceManager 

public string Create(string sKey, string sXmlParameters) 

**Parameters:** 

Name: sKey Type: string 
Description: 
The API security key. A valid API security key is required for every API call. 

Name: sXmlParameters Type: string 
Description: Values needed to create a new device. See the Additional Information  >section for XML format. 

Return Value: Type: string 
Description: Returns XML containing the status of the creation and if the status is 
Constants.ExternalServiceReturnCodes.SUCCEEDED, the ID of the new device. 

XMLParameters:

<PARAMETERS>  
    <NAME>string - up to 64 characters. Non-blank name of the device. 
    Must be unique within a gateway. 
    </NAME> 
    <DESCRIPTION>string - up to 1024 characters. The description of the new device. 
    </DESCRIPTION> (optional) 
    <TYPEID>string of DeviceType. The type of device. 
    </TYPEID> 
    <GATEWAYID>string - 32-character GUID. The ID of the gateway to associate with the 
    device. If this node is included, it must contain an ID of 
    a gateway that exists in the solution. 
    </GATEWAYID> (optional) 
    <INSTALLATIONDATETIME> 
    date time in UTC - greater than or equal to 
    1753-01-01 00:00:00.000 and less than or equal to 
    9999- 12-31 23:59:59.998. The date time that the device was installed. 
    </INSTALLATIONDATETIME> (optional - if not included, the installation 
         date time is set to the date time in UTC when the device is 
         created in the solution)  
    <SERIALNUMBER>string - up to 64 characters. The serial number of the device 
    </SERIALNUMBER> 
    <TIMEZONEID>string - time zone ID. The time zone ID of the device. 
    Call the TimeZoneManager.RetrieveList API to get a list of valid time zone IDs 
    </TIMEZONEID> (required for device type 'meter') 
    <HARDWAREVERSION>string - up to 32 characters. The hardware version of the device. 
    </HARDWAREVERSION> (optional) 
    <GEOGRAPHICCOORDINATES> 
     <LATITUDE>decimal - greater than or equal to -90 and less than or 
     equal to 90. The latitude geographical coordinate of the 
     device in decimal degrees. The value must be from the 
     WGS84 spatial reference system.                  
     If more than 6 digits after the decimal point are included, 
     the value will be rounded to 6 digits. 
     </LATITUDE> 
     <LONGITUDE> 
     decimal - greater than or equal to -180 and less than or 
     equal to 180. The longitude geographical coordinate of the 
     device in decimal degrees. The value must be from the 
     WGS84 spatial reference system. 
     If more than 6 digits after the decimal point are included, 
     the value will be rounded to 6 digits. 
     </LONGITUDE> 
    </GEOGRAPHICCOORDINATES> (optional) 
    <METER> 
     <ID>string - 12 hexadecimal characters.</ID> 
     <TRANSFORMERID>string - up to 128 characters.</TRANSFORMERID> 
     <DOWNLIMIT>integer - greater than or equal to 0 and less than or               
     equal to 65535. 
     </DOWNLIMIT> (optional) 
    <METER> 
</PARAMETERS> 

返回API淨荷格式:

<DEVICEID>string - 32-character GUID. The ID of the new device.</DEVICEID> 

的甲PI總是以下面的格式返回數據:

<RETURNS> 
     <STATUS> 
       String from Constants.ExternalServiceReturnCodes class. 
     </STATUS> 
     <APIPAYLOAD> 
       Additional information from the API call. Node may be empty. For 
       APIs that return information, that information will be shown in 
       the Return section. 
     </APIPAYLOAD> 
</RETURNS> 

所以在上面的例子中,有效載荷將類似於:

<RETURNS> 
     <STATUS> 
       SUCCEEDED 
     </STATUS> 
     <APIPAYLOAD> 
       <DEVICEID>string - 32-character GUID. The ID of the new device.</DEVICEID> 
     </APIPAYLOAD> 
</RETURNS> 

至於現在,我一直在努力設計類所有XML參數能夠對API中的參數和有效載荷進行序列化和反序列化,但定義這些參數非常耗時。下面給出了創建API參數和有效載荷的示例。 (簡單的例子使用get集)

DeviceManager創建參數

[XmlRoot(ElementName = "PARAMETERS")] 
public class Create 
{ 

    [XmlElement(ElementName = "NAME")] 
    public string Name { get; set; } 

    [XmlElement(ElementName = "DESCRIPTION")] 
    public string Description { get; set; } 

    [XmlElement(ElementName = "TYPEID")] 
    public string TypeId { get; set; } 

    [XmlElement(ElementName = "GATEWAYID")] 
    public string GatewayId { get; set; } 

    [XmlElement(ElementName = "INSTALLATIONDATETIME")] 
    public string InstallationDateTime { get; set; } 

    [XmlElement(ElementName = "SERIALNUMBER")] 
    public string SerialNumber { get; set; } 

    [XmlElement(ElementName = "TIMEZONEID")] 
    public string TimeZoneId { get; set; } 

    [XmlElement(ElementName = "HARDWAREVERSION")] 
    public string HardWareVersion { get; set; } 

    [XmlElement(ElementName = "GEOGRAPHICCOORDINATES")] 
    public CreateParametersGeoGraphicCoordinates GeographicCoordinates { get; set; } 

    [XmlElement(ElementName = "METER")] 
    public CreateMeter Meter { get; set; } 
} 

public class CreateMeter 
{ 
    [XmlElement(ElementName = "NEURONID")] 
    public string NeuronId { get; set; } 

    [XmlElement(ElementName = "TRANSFORMERID")] 
    public string TransformerId { get; set; } 

    [XmlElement(ElementName = "UTILITYID")] 
    public string UtilityId { get; set; } 

    [XmlElement(ElementName = "LONTALKKEY")] 
    public string LonTalkKey { get; set; } 

    [XmlElement(ElementName = "DOWNLIMIT")] 
    public string DownLimit { get; set; } 
} 

public class CreateParametersGeoGraphicCoordinates 
{ 
    [XmlElement(ElementName = "LATITUDE")] 
    public string Latitude { get; set; } 

    [XmlElement(ElementName = "LONGITUDE")] 
    public string Longitude { get; set; } 
} 

而對於有效載荷我有以下的通用類和DeviceManager。創建有效負載特定類:

創建有效載荷

public class CreatePayLoad 
{ 
    [XmlElement(ElementName = "DEVICEID")] 
    public string DeviceId { get; set; } 
} 

有效載荷

[XmlRoot(ElementName = "RETURNS")] 
public class PayLoad<T> where T : new() 
{ 
    public PayLoad() 
    { 
     ApiPayLoad = new T(); 
    } 

    /// <summary> 
    /// Contains the payload from the command. 
    /// </summary> 
    [XmlElement(ElementName = "APIPAYLOAD")] 
    public T ApiPayLoad { get; set; } 

    /// <summary> 
    /// Status of the call 
    /// </summary> 
    [XmlElement(ElementName = "STATUS")] 
    public string Status { get; set; } 
} 

所以,在我的代碼,我可以做呼叫方式如下:

例使用

//Create the parameters 
var parameters = new Create 
        { 
         Description = "Description", 
         GatewayId = "GatewayId", 
         Name = "NameOfDevice", 
         GeographicCoordinates = new CreateParametersGeoGraphicCoordinates 
                { 
                 Latitude = "Lat", 
                 Longitude = "Long" 
                }, 
         Meter = new CreateMeter 
            { 
             TransformerId = "ID", 
             DownLimit = "120" 
            } 
        }; 

//Serialize the parameters to xml 
string sXmlParameters = Helper.SerializeToXml<Create>(parameters); 

//API call 
string apiPayLoad = DeviceManager.Create(apiKey, sXmlParameters); 

//Deserialize payload 
var payLoad = Helper.DeserializeFromXml<PayLoad<CreatePayLoad>>(apiPayLoad); 

有人可以請貢獻的想法和更好的方法來管理這個? 請記住,系統中有大約300個方法,其中一些具有非常複雜的xml參數,其中一些屬性是可選的,一些是使用屬性A,B或C時必須的,等等。

我一直在看XSD.exe,但生成的代碼並不整齊,並且它不能很好地處理集合。

一位朋友還提出了T4模板,其中可以根據模板生成類,但我沒有真正找到任何好的例子。

我不知道我是否已經以良好的方式解釋了自己,如果我不清楚 - 請讓我知道,我會盡力詳細說明。

謝謝 AMR-它

回答

0

它們不是強類型的,所有的API都採用sXmlParameters,並且僅由文本文檔定義。使用XSD.exe,我製作了XML示例,然後生成了xsd,並從中生成了一些.cs文件。但是,這是一項非常耗時的任務。

我被推薦查看DSL流暢接口,這可以幫助我構建sXmlParameters。

var result = DeviceManager.Create(apiKey, 
    Parameters. 
    .Type(Parameters.Create) 
    .Name("Name of Device") 
    .Description("Description of Device") 
    .Coordinates("Lat","Long") 
    .Validate() 
    .asXML() 
); 

利用這一點,我可以從代碼構造參數,並且有一個基類返回參數作爲XML前驗證所需的字段。

但是,爲每個結果映射PayLoads仍然是一項耗時的任務。我正在考慮使用T4模板來生成基於XML或similair的類。

0

愚蠢的提問時間:所以你是說沒有任何的API是強類型的?這意味着,所有的簽名是:

public string Create(string sKey, string sXmlParameters) 

和輸入「sXmlParameters」參數僅通過文本文檔定義的模式?如果是這樣的話,那麼我認爲你正在推翻事情,編寫響應的解析方法就像創建類並使用模板和轉換技術將響應轉換爲對象一樣高效。

但是,你提到XSD.exe,所以也許有定義模式的輸入和輸出?如果是這樣的話,我會使用XSD工具創建這些類定義,而不用擔心它們不是「整潔的眼​​睛」 - 你從來沒有看過那些c#文件,只是使用對象。就他們對集合的弱點而言 - 如果你想過濾/排序/檢查/遍歷複雜的嵌套集合數據,我建議你看看LINQ查詢表達式;他們會讓你快速抓住你需要的物體。當然,他們對對象實例化沒有多大幫助,但我認爲沒有很好的解決方法。