【提出问题】
几乎每个软件系统里都会用到数据字典,比如说地市列表,CRM里的联系人的类型,文章的分类等等。这些数据字电的表现形式一般为下CheckBoxList,RadioBoxList,DropdownList,ListBox这几种,有单选的,有多选的,一般我们都是分别来建数据表,这样重用性太差,我们应该把这些公用的东西提取出一套系统用来复用。
【设计思路】
我们可以做一个web服务来管理词典和词条,这样不用给每个词典建表,而且一些相对比较固定的词典,比如说一些地市分类等这些,还可以公开让其它isv来使用。
【下载代码】
https://files.cnblogs.com/onlytiancai/WordBookService.rar
【声明】
1、WS是WawaSoft的缩写
2、wb是wordbook的缩写
【数据结构设计】
表:WS_WordBookCategory
guid:guid 主键
Category:string 词典分类名称,不能重复
Description:string 词典分类描述
CreateUser:string 创建人
IsChooseMuilti:bool 是否可多选
IsTree:bool 是否是树型的
Enabled:bool 是否启用
CreateDate:date 创建时间
表:WS_WordBook
guid:guid 主键
category:string 词典分类名称
WBName:string 词条名称
WBValue:string 词条值
parentid:guid 父类ID,支持树结构
【业务服务接口设计】
public interface IWBService
{
Guid AddWord(string category, string wbName, string wbValue, Guid parentid);
[WebMethod(Description = "删除词条")]
void DeleteWord(string category, string wbName);
[WebMethod(Description = "删除词条类别")]
void DeleteWordBookCategory(string name);
[WebMethod(Description = "编辑词条")]
void EditWord(string category, string wbName, string wbValue);
[WebMethod(Description = "获取所有词条分类")]
string[] GetAllWordBookCategory();
因为接口不能序列化,所以这三个方法不能暴露为web方法
[WebMethod(Description = "判断是否存在某个词条分类")]
bool HasWordBookCategory(string category);
[WebMethod(Description = "注册词条类别")]
Guid RegisterWordBookCategory(string name, string description, string createUser, bool isTree, bool isChooseMuilti);
[WebMethod(Description = "搜索词条分类")]
string[] SearchWordBookCategory(string key);
}
[WebServiceBinding(Name = "WBService", Namespace = "http://www.myservices.cn/wordbookservice/")]
public interface IWBServiceWeb : IWBService
{
[WebMethod(Description = "获取词条分类")]
string GetWordBookCategoryStr(string name);
[WebMethod(Description = "获取某个分类的词条")]
string GetWordsStr(string category);
[WebMethod(Description = "获取某个词条")]
string GetWordBookStr(string category, string wbName);
[WebMethod(Description = "添加词条")]
Guid AddWordStr(string category, string wbName, string wbValue, string parentid);
}
【开发步骤】
1、写业务文档,画用例图,确认需求;
2、写设计文档,画类图,数据库模型图,生成数据库;
3、建立vs解决方案,创建BLL项目和WEB服务,根据数据库生成实体接口(用NBear的工具);
4、参考画的类图,在VS类设计器里设计业务服务的类(能用visio生成代码也行,不过一般visio里画的类图都是中文名称,为了便于交流,所以生成代码不好);
5、把刚才设计好的业务类用重构提取成一个接口,然后把这个接口设计成web服务接口,因为咱们最终我们要用web服务发布。针对接口编程是个好习惯。(因为NBear使用接口类型实体,当方法的返回类型是接口实体的话,无法序列化,就不能用web服务传输,所以我创建了两个接口);
6、右键点业务类,创建单元测试项目,为所有的公有方法创建单元测试用例,把自动生成的代码稍微改改就行,这就是TDD吧;
7、利用NBear框架类开发业务类,刚才只是生成了一些业务方法的框架,现在填充代码。
8、写完业务代码当然要进行单元测试了;
9、在web服务项目里创建一个asmx,继承自第五步的WEB服务接口,然后调用业务层的方法来开发每个web方法,记着用接口来引用业务组件;
10、部署、测试。
【改进】
因为NBear使用接口实体,所以我把一些Web方法用NBear.Common.EntitySerializer序列化成字符串再返回。这样可能会使互操作成为问题,如果是java或者javascript消费这个web服务,得自己解序列化返回在字符串。做WEB服务返回的类型最好要符合xsd规范,这样web服务客户端可以用工具把wsdl生成使用服务的代理和相关类。
改进的方法可以这样,可以根据实体接口的成员创建响应的结构,然后把返回的接口实体和数组填充到结构里,最后把这些结构和结构数组返回给客户。客户端生成代理的时候会自动识别这些结构并生成客户端的类。