我肯定会为每种请求类型添加一个新类.是的,您可能需要编写大量代码,但它会更安全.关键(对我来说)是谁会写这段代码?让我们把这个答案读到最后(或直接跳转到最后建议的选项).
在这些例子中,我将使用Dictionary< string,string>对于通用对象,但您可能/应该使用适当的类(不公开字典),数组,通用枚举或任何您感觉舒服的东西.
1.(几乎)强类型类
每个请求都有自己的强类型类,例如:
abstract class Request {
protected Request(string name) {
Name = name;
}
public string Name { get; private set; }
public Dictionary Args { get; set; }
}
sealed class AuthenticationRequest : Request
{
public AuthenticationRequest() : base("AuthenticationRequest") {
}
public string UserName { get; set; }
public string Password { get; set; }
}
请注意,您可以切换到完整类型的方法,同时删除字典for Args,以支持类型化的类.
优点
您认为缺点(变化更难)是IMO的一大好处.如果您更改服务器端的任何内容,那么您的请求将失败,因为属性将不匹配.没有细微的错误,因为字符串中的拼写错误而导致字段未初始化.
它是强类型的,然后您的C#代码更容易维护,您有编译时检查(名称和类型).
重构更容易,因为IDE可以为您完成,无需盲目搜索和替换原始字符串.
实现复杂类型很容易,你的参数不仅限于普通字符串(现在可能不是问题,但稍后你可能会要求它).
缺点
您可以在一开始就编写更多代码(但是类层次结构也可以帮助您发现依赖关系和相似之处).
2.混合方法
键入公共参数(名称和参数),但其他所有参数都存储在字典中.
sealed class Request {
public string Name { get; set; }
public Dictionary Args { get; set; }
public Dictionary Properties { get; set; }
}
使用混合方法,您可以保留类型化类的一些好处,但不必定义每种请求类型.
优点
它的实现速度比几乎/完全类型的方法更快.
您有一定程度的编译时检查.
您可以重用所有代码(我假设您的Request类也将重用于Response类,如果您将辅助方法 – 例如GetInt32() – 移动到基类,那么您将编写一次代码).
缺点
它是不安全的,错误的类型(例如,从字符串属性中检索整数)在运行时实际发生错误之前不会被检测到.
更改不会破坏编译:如果更改属性名称,则必须手动搜索使用该属性的每个位置.自动重构不起作用.这可能会导致很难检测到错误.
您的代码将被字符串常量污染(是的,您可以定义const字符串字段)和强制转换.
您的参数很难使用复杂类型,并且您只能使用字符串值(或者可以轻松序列化/转换为纯字符串的类型).
3.动态
动态对象允许您定义一个对象并将其作为类型化类访问它们,但它们实际上将在运行时动态解析.
dynamic request = new ExpandoObject();
request.Name = "AuthenticationRequest";
request.UserName = "test";
请注意,您也可以使用这种易于使用的语法:
dynamic request = new {
Name = "AuthenticationRequest",
UserName = "test"
};
优点
如果向架构添加属性,则不需要在不使用代码时更新代码.
它比无类型方法更安全.例如,如果请求填写为:
request.UserName = "test";
如果你写错了:
Console.WriteLine(request.User);
您将遇到运行时错误,并且仍然有一些基本的类型检查/转换.
代码比完全无类型的方法更具可读性.
拥有复杂类型很容易也可能.
缺点
即使代码比完全无类型的方法更具可读性,您仍然无法使用IDE的重构功能,并且几乎没有编译时检查.
如果您更改了架构中的属性名称或结构,并且忘记更新代码(某处),那么只有在运行时才会出现错误,当您使用它时.
4.自动生成的强类型类
最后但最好的……到目前为止,我们确实忘记了一件重要的事情:JSON具有可以验证的模式(参见json-schema.org).
它有用吗?您可以从该模式生成完全类型的类,让我们看看JSON schema to POCO.如果您没有/不想使用模式,您仍然可以从JSON示例生成类:查看JSON C# Class Generator项目.
只需为每个请求/响应创建一个示例(或模式),并使用自定义代码生成器/构建任务从中构建C#类,如下所示(另请参见MSDN about custom build tools):
Cvent.SchemaToPoco.Console.exe -s %(FullPath) -o .\%(Filename).cs -n CsClient.Model
临
以上解决方案的所有优点.
缺点
没有什么我能想到的……