如何设计包含网络服务结果的 class
How to design a class containing the result from a webservice
问题
我将不同的网络服务称为 returns json 字符串。我将这些字符串解析为自定义对象并将它们保存在名为 APIResult 的 "result class" 中。例如,一个网络服务 returns 列表 OBJ1,另一个 returns OBJ2,有时还会返回两个或更多对象。结果 class 返回给使用对象调用它的方法和一个指示请求是否成功的布尔值。
这行得通,但是当我不得不调用许多不同的网络服务时,class 变得很丑陋。现在我有 7 个属性,如 OBJ1、OBJ2、List、List 等。为了避免向 APIResult 添加更多属性 class 我想重新设计它以使其更加灵活,但我不确定什么是最好的方法。
想法
泛型似乎是个好主意。我可以使用 new APIResult(ObjectType) 初始化我的 class,然后拥有一个或多个属性 T Data1。拥有三个属性 T Data1、T Data2、T Data3 还是有点难看。我也不确定我是否可以在没有反射的情况下将对象从 json 解析为通用类型,这是否会减慢速度。
你有什么建议吗?
这里需要考虑的事情很少
您需要 APIResult class 吗?你打算用它做什么?如果您有一个记录良好的 REST api(例如一个 odata api),那么响应就会得到很好的描述,您可以验证您得到的响应是否是您需要的。不然配不上怎么办?
如果您只是将其解析到您的模型中,您甚至可以考虑使用通用 JObject 来保存您的响应。然后您可以检查此 JObject 上的 properties/subobjects。您甚至可以将它传递给 (newtonsoft) json 序列化程序,并让调用方法说明它应该是什么样子。
您的回复有何商业意义?结果总是一个硬名称。但是,如果您拥有 FirstName、LastName、AddressList 等属性,那么它会变得更好。
将结果状态与实际数据分开。
正如您所建议的,泛型是一个有用的工具。创建一个结果状态 class 封装 success/failure 逻辑并(在成功的情况下)提供对数据的访问。
这可能看起来像这样:
public class ApiResult<T>
{
public bool Success { get; }
public T Dto { get; }
public ApiResult(bool success, T dto)
{
Success = success;
Dto = dto;
}
}
现在将数据 class 设计成没有任何逻辑的简单 属性 包。它们的唯一目的是定义从特定 Web 服务返回的数据。另外,不要尝试建立深继承层次结构。将相同的 属性 添加到两个不同的 DTO 是可以的。
public class Dto1
{
string PropertyA { get; set; }
string PropertyB { get; set; }
}
public class Dto2
{
string PropertyA { get; set; }
string PropertyC { get; set; }
}
有了这个,您现在可以为您调用的 Web 服务定义代理。代理界面可能如下所示:
public interface ISomeServiceProxy
{
ApiResult<Dto1> GetTheThing(string someParam);
}
在该接口的实现中,您将希望使用 JSON.NET 将响应反序列化为 Dto1
并将其包装在 ApiResult
.
中
此外,您可能希望让代理使用 async
。我在这些示例中省略了它,转换它们很简单。
问题 我将不同的网络服务称为 returns json 字符串。我将这些字符串解析为自定义对象并将它们保存在名为 APIResult 的 "result class" 中。例如,一个网络服务 returns 列表 OBJ1,另一个 returns OBJ2,有时还会返回两个或更多对象。结果 class 返回给使用对象调用它的方法和一个指示请求是否成功的布尔值。
这行得通,但是当我不得不调用许多不同的网络服务时,class 变得很丑陋。现在我有 7 个属性,如 OBJ1、OBJ2、List、List 等。为了避免向 APIResult 添加更多属性 class 我想重新设计它以使其更加灵活,但我不确定什么是最好的方法。
想法 泛型似乎是个好主意。我可以使用 new APIResult(ObjectType) 初始化我的 class,然后拥有一个或多个属性 T Data1。拥有三个属性 T Data1、T Data2、T Data3 还是有点难看。我也不确定我是否可以在没有反射的情况下将对象从 json 解析为通用类型,这是否会减慢速度。
你有什么建议吗?
这里需要考虑的事情很少
您需要 APIResult class 吗?你打算用它做什么?如果您有一个记录良好的 REST api(例如一个 odata api),那么响应就会得到很好的描述,您可以验证您得到的响应是否是您需要的。不然配不上怎么办?
如果您只是将其解析到您的模型中,您甚至可以考虑使用通用 JObject 来保存您的响应。然后您可以检查此 JObject 上的 properties/subobjects。您甚至可以将它传递给 (newtonsoft) json 序列化程序,并让调用方法说明它应该是什么样子。
您的回复有何商业意义?结果总是一个硬名称。但是,如果您拥有 FirstName、LastName、AddressList 等属性,那么它会变得更好。
将结果状态与实际数据分开。
正如您所建议的,泛型是一个有用的工具。创建一个结果状态 class 封装 success/failure 逻辑并(在成功的情况下)提供对数据的访问。
这可能看起来像这样:
public class ApiResult<T>
{
public bool Success { get; }
public T Dto { get; }
public ApiResult(bool success, T dto)
{
Success = success;
Dto = dto;
}
}
现在将数据 class 设计成没有任何逻辑的简单 属性 包。它们的唯一目的是定义从特定 Web 服务返回的数据。另外,不要尝试建立深继承层次结构。将相同的 属性 添加到两个不同的 DTO 是可以的。
public class Dto1
{
string PropertyA { get; set; }
string PropertyB { get; set; }
}
public class Dto2
{
string PropertyA { get; set; }
string PropertyC { get; set; }
}
有了这个,您现在可以为您调用的 Web 服务定义代理。代理界面可能如下所示:
public interface ISomeServiceProxy
{
ApiResult<Dto1> GetTheThing(string someParam);
}
在该接口的实现中,您将希望使用 JSON.NET 将响应反序列化为 Dto1
并将其包装在 ApiResult
.
此外,您可能希望让代理使用 async
。我在这些示例中省略了它,转换它们很简单。