是否可以在AsyncAPI中创建具有特定值的枚举?在我的遗留c#代码中有这样一个枚举
public enum OrderStatus
{
Ordered = 30,
UnderDelivery = 40,
Deliveret = 50,
Cancelled = 99
}我希望在AsyncAPI中创建相同的枚举,具有相同的值。但是,似乎不能在异步API中指定值。我是不是遗漏了什么?有没有其他的解决办法?
发布于 2022-06-07 12:49:17
事实并非如此,至少在一般意义上是如此。
使用AsyncAPI 2.4,您可以使用不同模式格式 (schemaFormat)定义有效载荷,默认情况下,这是一个AsyncAPI模式对象,它是JSON草案7的超集。
查看JSON草案7,您将发现不可能定义带有关联名称(如Ordered和UnderDelivery )的枚举值。这意味着定义它的唯一方法是这样的:
{
"title": "OrderStatus",
"type": "number",
"enum": [
30,
40,
50,
99
]
}这是因为JSON侧重于验证JSON数据,而在JSON世界中,不存在与枚举值相关联的名称。这与编程语言完全相关。
解决方案
有几个解决方案,你可以如何进行,让我强调一种方式,我认为它可以实现。
规范扩展
如果使用默认的AsyncAPI 2.4.0Schema对象,则使用AsyncAPI允许您添加自己的扩展,如:
{
"title": "OrderStatus",
"type": "number",
"enum": [
30,
40,
50,
99
],
"x-enumNames": {
30: "Ordered",
40: "UnderDelivery",
50: "Deliveret",
99: "Cancelled"
}
}如果使用纯JSON草案7,这也会有效,因为任何额外的属性都是允许的。
在较新版本的JSON中,它们引入了一些名为词汇表的内容,可以对此特性进行标准化。我开始了一些关于代码生成词汇表的工作--不幸的是,还有许多其他领域需要首先解决,所以我没有足够的带宽来推动它的发展。
生成枚举模型
不管您如何使用规范来定义它,我希望您希望工具在代码生成中生成“精确”的枚举模型,因此这里有一种方法。
莫迪纳是一个开源工具,正在为这些情况而开发。我添加了一个测试用例,以展示如何为Modelinav0.59完成测试用例。
const generator = new CSharpGenerator({
presets: [
{
enum: {
item: ({model, item, content}) => {
// Lets see if an enum has any associated names
const hasCustomName = model.originalInput !== undefined && model.originalInput['x-enumNames'] !== undefined;
if (hasCustomName) {
// Lets see if the specific value has an associated name
const customName = model.originalInput['x-enumNames'][item];
if (customName !== undefined) {
return customName;
}
}
return content;
}
}
}
]
});Csharp生成器被指示使用自定义预置(可以看作是Node.js中间件)用于枚举呈现器。在这里,我们添加了一个中间件来覆盖每个枚举"item"/value的名称,这取决于它是否有我们的扩展。
这将导致跟随生成模型
public enum OrderStatus
{
Ordered,
UnderDelivery,
Deliveret,
Cancelled
}
public static class OrderStatusExtensions
{
public static dynamic GetValue(this OrderStatus enumValue)
{
switch (enumValue)
{
case OrderStatus.Ordered: return 30;
case OrderStatus.UnderDelivery: return 40;
case OrderStatus.Deliveret: return 50;
case OrderStatus.Cancelled: return 99;
}
return null;
}
public static OrderStatus? ToOrderStatus(dynamic value)
{
switch (value)
{
case 30: return OrderStatus.Ordered;
case 40: return OrderStatus.UnderDelivery;
case 50: return OrderStatus.Deliveret;
case 99: return OrderStatus.Cancelled;
}
return null;
}
}https://stackoverflow.com/questions/72530361
复制相似问题