gpt4 book ai didi

c# - 消费/包装大型网络服务的架构技巧

转载 作者:太空宇宙 更新时间:2023-11-03 16:34:19 29 4
gpt4 key购买 nike

我正在寻找实现智能架构的良好实践,以及处理针对具有许多不同 wdsl web 服务的系统的集成的方法。

我已经有 2 年的爱好使用 C# 进行开发了~,因此我并不总是使用正确的术语,但我会尝试描述我正在寻找的东西。

我发布这篇文章的主要原因是想了解我应该阅读的领域、要实现的设计模式以及如何以良好的方式管理 API 调用。

我正在针对提供大量不同 API 的系统进行集成。每个 API 有 20-30 个方法。每个 API 都采用许多 XML 格式的参数。

为了给您一个概念,我以下面的 API 为例,它是 DeviceManager API 和 Create 方法,用于在系统中创 build 备。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,但生成的代码看起来并不整洁,而且它不能很好地处理集合。

一位 friend 还提出了 T4 模板,其中可以根据模板生成类,但我并没有真正找到任何好的示例。

我不确定我是否以一种好的方式解释了自己,如果我不清楚 - 请告诉我,我会尽力详细说明。

谢谢,amr-it

最佳答案

愚蠢的提问时间:所以你是说没有一个 API 是强类型的?意思是,所有签名都是:

public string Create(string sKey, string sXmlParameters) 

输入“sXmlParameters”参数的架构仅由文本文档定义?如果是这样,那么我认为您想多了,为响应编写解析方法与创建类并使用模板和转换技术将响应转换为对象一样有效。

但是,您提到了 XSD.exe,所以也许有定义的输入和输出模式?如果是这样的话,我会使用 XSD 工具创建这些类定义,而不用担心它们“不美观”——您永远不会查看那些 c# 文件,您只是使用对象。就它们在集合方面的弱点而言——如果您尝试过滤/排序/检查/遍历复杂的嵌套集合数据,我建议您查看 LINQ 查询表达式;他们会让您快速抓取所需的元素。当然,它们对对象实例化帮助不大,但我认为没有快速解决方法。

关于c# - 消费/包装大型网络服务的架构技巧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9667714/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com