在前段时间,接触一个很喜欢钉钉并且已在内部场景广泛使用钉钉进行工厂内部管理的客户,如钉钉考勤、日常审批、钉钉投影、钉钉门禁等等方面,才体会到原来钉钉已经已经在企业上可以用的很广泛的,因此回过头来学习研究下钉钉的一些业务范围和其SDK的开发工作。钉钉官方的SDK提供了很多方面的封装,不过相对于Java,.NET版本的一直在变化当中,之前研究钉钉C#版本SDK的时候发现一些问题反映给钉钉开发人员,基本上得不到好的解决和回应,而在使用官方的SDK的时候,有些数据竟然无法正常获取(如角色的信息等),而且官方的SDK使用的时候觉得代码较为臃肿,因此萌生了对钉钉官方SDK进行全面重构的想法。本系列随笔将对整个钉钉SDK涉及的范围进行分析重构,并分享使用过程中的效果和乐趣。
1、钉钉的介绍
钉钉(DingTalk)是阿里巴巴集团专为中国企业打造的免费沟通和协同的多端平台,提供PC版,Web版和手机版,支持手机和电脑间文件互传。 钉钉是阿里集团专为中国企业打造的通讯、协同的免费移动办公平台,帮助企业内部沟通和商务沟通更加高效安全。


2、使用钉钉官方SDK存在的一些问题或不足
一般我们在开发的时候,倾向于使用现有的轮子,而不是重复发明轮子。不过如果轮子确实不适合或者有更好的想法,那就花点功夫也无妨。
在使用原有的钉钉SDK的时候,发现存在以下一些问题。
1)部分SDK由于参数或者其他问题,导致获取到的JSON数据无法序列化为正常的属性,如前段时间的角色列表信息部分(后来修复了这个问题)。
2)使用SDK对象的代码过于臃肿,一些固定化的参数在使用过程中还需要传入,不太必要而且增加了很多调用代码。
3)对JSON序列化的部分,没有采用JSON.NET(Newtonsoft.Json.dll)的标准化方案,而是利用了自定义的JSON解析类,导致整个钉钉SDK的解析过程繁杂很多。
4)对整个钉钉SDK的设计显得过于复杂而不容易修改。
5)其他一些看不惯的原因
为了避免大范围的变化导致整个使用接口也变化,我在重构过程中,尽量还是保留钉钉的使用接口,希望使用者能够无缝对接我重构过的钉钉SDK接口,因此我在极力简化钉钉SDK的设计过程的时候,尽量兼容使用的接口。
而且由于我引入了Json.NET的对象标准序列化和反序列化的处理后,发现代码确实简化了不少,对于重构工作提供了非常的方便。
我们来对比一下原有钉钉SDK接口的使用代码和重构钉钉SDK的使用代码。
IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken"); OapiGettokenRequest request = new OapiGettokenRequest(); request.Corpid = corpid; request.Corpsecret = corpSecret; request.SetHttpMethod("GET"); OapiGettokenResponse response = client.Execute(request); return response;
上面的代码就是钉钉标准官方SDK的使用代码,用来获取token信息的一个接口。
其实这个初始化DefaultDingTalkClient,并准备使用 OapiGettokenRequest来获取应答对象的时候,我们可以把这个URL(https://oapi.dingtalk.com/gettoken)封装在请求里面的,不需要使用的时候再去找这个URL,而且对应OapiGettokenRequest 请求的时候,数据提交方式POST或者GET方式也应该确定下来了,不需要用户再去设置较好。
用户参数比较少的情况下,可以使用构造函数传递,减少代码的行数。
然后利用扩展函数的方式,我们还可以进一步减少调用的代码行数的。
我们来看看,我重构代码后的调用过程,简化为两行代码即可:
var request = new OapiGettokenRequest(corpid, corpSecret); var response = new DefaultDingTalkClient().Execute(request);
使用扩展函数的辅助,我们还可以简化为一行代码,如下所示
var token = new OapiGettokenRequest(corpid, corpSecret).Execute();
对于前面N行代码,变为目前的一行代码,效果是一样的,这个就是我希望的效果:简单是美。
如果对于多个Request的调用,我们也可以重用DingTalkClient对象的,如下代码所示。
var client = new DefaultDingTalkClient(); var tokenRequest = new OapiGettokenRequest(corpid, corpSecret); var token = client.Execute(tokenRequest); if (token != null && !token.IsError) { string id = "1"; var request = new OapiDepartmentListRequest(id); var dept = client.Execute(request, token.AccessToken); ...................
当然,由于请求对象和应答对象,我依旧保留了原来对象的名称,只是采用了基于JSON.NET的方式来重新处理了一下对象的定义。
例如对于Token的请求和应答对象,原来的Token应答对象定义如下所示
/// <summary> /// OapiGettokenResponse. ///

