abp模块化开发之通用树2:设计思路及源码解析

abp模块化开发之通用树2:设计思路及源码解析

 

 

上一篇大概说了下abp通用树形模块如何使用,本篇主要分析下设计思路

日常开发中会用到很多树状结构的数据,比如:产品的多级分类、省市区县,大多数系统也会用到类似“通用字典/数据字典”的功能,为系统各个地方提下拉框选择的数据源。abp提供了一个模块化系统,只要按它的约定就可以实现一个通用的树形数据的模块,这样公司的多个系统都可以使用,也可以用类似nuget的方式提供给别人使用。

先列举下它的功能

通过nuget方便安装和升级

配置简单

默认已经提供“通用字典”功能

实体、管理器、应用服务都是抽象类,结合泛型 狠容易扩展实现自己的树形结构

 

 

 

 

二、必备知识

这不是abp入门级的文章,是探讨系统模块化开发的一种思路。所以要求对abp有经验,完整看过abp文档,对涉及到的模块、依赖注入、启动配置、权限、菜单、本地化等等概念有清晰的认识

 

三、包和源码

源码地址:https://github.com/bxjg1987/abpGeneralModules
nuget:Install-Package BXJG.GeneralTree -Version 1.0.2
源码仓库中还有通用的文件模块、附件模块,后期会讲讲;nuget搜索bxjg可以找到这几个相关的包

 

四、总体设计

为了便于说明,我们以常见的产品无限级分类来说明,所有树形结构数据有这么几个特点:

有个ParentId属性指向父级节点,

有个code,数据格式类似:00001.00001,一个是能简单体现产品分类节点的层级结构,二个是方便将来查询某个分类及其后代分类下的所有产品 where categoryCode like '00001%

当然还有Name属性

上面说了定义实体类的关键点,然后我们需要提供一个对应的Manager(这个是abp定义领域服务的套路),来主负责CRUD和节点间的移动操作,其实最麻烦的就是自动处理code,新增和修改时要根据所属父节点的code自动生成子节点的code,移动时就更复杂了,要重新计算当前节点及其兄弟节点及其所有后代节点的code,这还涉及到目标节点和源节点。为了便于扩展,上面的领域服务还得将被处理的实体泛型话,文章后续会具体说明

最后按abp套路我们还需要提一个应用服务,它核心操作就是调用上面提供的Manager做节点的crud操作,在此基础上按abp的套路应该提供权限验证、处理实体与dto之间的转换。同理为了便于将来模块的使用方进行扩展,我们应该应用抽象类和泛型的威力,文章后续会具体说明

最后我们如何提供Repository呢?参考abp zero的思路,我们将这个遗留到调用方来定义。在我们的领域服务Manager和应用服务AppService中都是通过依赖注入注入的IRepository<TEntity,TKey>

核心的3个东东定义好后,我们分别实现一个默认类,实现一个“通用字典”,将来调用方可以继承我们的类并提供泛型参数来实现他们自己的树形结构。
另外我们将所有的代码放在一个项目中,因为模块足够小,功能少  这样调用方用起来更方便

注意一点,上面以产品分类来说明只是便于理解,既然要提供扩展能力,设计时只能从抽象的角度来看待树形数据,否则设计出来的东西很容易最后发现不够抽象,此废话只可意会不可言传

最后是abp相关的:本地化定义、模块定义及依赖关系、权限提供器、菜单提供器、动态webapi的处理

五、实体类

实体类我这里只是说明,具体源码请访问顶部的github

GeneralTreeEntity<TEntity>

它定义了树形结构数据的通用树形,Id、Code、Name、Parent等
泛型TEntity是子节点的类型,由于是树,实际上也是父节点的类型,这种设计是方便将来模块使用方在实现自定义的树形结构时拿到的Parent树形和Children树形,是他们自己定义的类型
主键Id属性,我定死了long类型,其实也可以使用泛型的TKey,思来想去简单起见直接定死吧

public class GeneralTreeEntity : GeneralTreeEntity<GeneralTreeEntity>

为了提供我们默认实现的“通用字典”功能,我们定义一个默认的子类GeneralTreeEntity,将来系统中那些简单的数据可以直接使用它
IsSysDefine表示此节点是否是系统预定义的,将来不允许删除
IsTree是否是树形,将来可能会用到,因为某些下拉框数据可能不需要多层次的,比如:民族,学历

六、领域服务

按套路我们提供一个抽象的领域服务Manager类,和一个为了实现“通用字典”功能的默认实现

public abstract class GeneralTreeManager<TEntity> : DomainService  where TEntity : GeneralTreeEntity<TEntity>

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxsxw.html