【发布时间】:2012-03-18 01:31:34
【问题描述】:
我正在寻找实现智能架构的良好实践以及处理与具有许多不同 wdsl Web 服务的系统的集成的方法。
我已经有 2 年的时间使用 C# 进行开发了~,因此我并不总是使用正确的术语,但我会尝试描述我在寻找什么。
我发布这篇文章的主要原因是为了了解我应该阅读的领域、要实现的设计模式以及如何以良好的方式管理 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.
XML参数:
<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; }
}
对于 PayLoads,我有以下通用类和 DeviceManager.Create Payload 特定类:
创建有效负载
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 模板,可以根据模板生成类,但我并没有真正找到任何好的示例。
我不确定我是否以一种好的方式解释了自己,如果我不清楚 - 请告诉我,我会尽力详细说明。
谢谢, 好啦
【问题讨论】:
标签: c# web-services architecture