簡體   English   中英

消費/包裝大型Web服務的體系結構技巧

[英]Tips on architecture for consuming/wrapping large webservice

我正在尋找實現智能體系結構的良好實踐以及針對具有許多不同wdsl 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> 

API始終以以下格式返回數據:

<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 set的簡單示例)

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.Create有效載荷特定的類:

創建有效載荷

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-it

愚蠢的提問時間:您是說沒有API是強類型的嗎? 意思是,所有簽名都是:

public string Create(string sKey, string sXmlParameters) 

並且輸入“ sXmlParameters ”參數的模式僅由文本文檔定義嗎? 如果真是這樣,那么我想您是想太多了,為響應編寫解析方法與創建類以及使用模板和轉換技術將響應轉換為對象一樣有效。

但是,您提到XSD.exe,所以也許有定義的輸入和輸出架構? 如果是這樣,我將使用XSD工具創建這些類定義,而不用擔心它們不是“整潔的外觀”-您從不看那些c#文件,而只是使用對象。 關於它們在集合方面的弱點-如果您要過濾/排序/檢查/遍歷復雜的嵌套集合數據,建議您查看LINQ查詢表達式; 它們將使您快速獲取所需的對象。 當然,它們對對象實例化沒有多大幫助,但是我認為沒有快速解決方案。

它們不是強類型的,所有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返回之前驗證必填字段。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM