一、前言
上一篇大概说了下abp通用树形模块怎样利用,本篇主要分析下计划思绪。
一样平常开发中会用到许多树状结构的数据,好比:产物的多级分类、省市区县,大多数体系也会用到雷同“通用字典/数据字典”的功能,为体系各个地方提下拉框选择的数据源。abp提供了一个模块化体系,只要按它的约定就可以实现一个通用的树形数据的模块,如许公司的多个体系都可以利用,也可以用雷同nuget的方式提供给别人利用。
先罗列下它的功能
- 通过nuget方便安装和升级
- 设置简朴
- 默认已经提供“通用字典”功能
- 实体、管理器、应用服务都是抽象类,团结泛型 狠容易扩展实现本身的树形结构
二、必备知识
这不是abp入门级的文章,是探究体系模块化开发的一种思绪。所以要求对abp有履历,完备看过abp文档,对涉及到的模块、依赖注入、启动设置、权限、菜单、当地化等等概念有清晰的认识
三、包和源码
源码地点:https://github.com/bxjg1987/abpGeneralModules nuget:Install-Package BXJG.GeneralTree -Version 1.0.2 在线地点: http://test.cqsifang.com/ 账号暗码:admin zlj.com (别胡来,拜托...) 源码堆栈中尚有通用的文件模块、附件模块,后期会讲讲;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
焦点的3个东东界说好后,我们分别实现一个默认类,实现一个“通用字典”,未来调用方可以继续我们的类并提供泛型参数来实现他们本身的树形结构。 另外我们将全部的代码放在一个项目中,因为模块充足小,功能少 如许调用方用起来更方便
注意一点,上面以产物分类来阐明只是便于明确,既然要提供扩展本领,计划时只能从抽象的角度来对待树形数据,否则计划出来的东西很容易末了发现不敷抽象,此废话只可意会不可言传
末了是abp干系的:当地化界说、模块界说及依赖关系、权限提供器、菜单提供器、动态webapi的处置惩罚
五、实体类
实体类我这里只是阐明,具体源码请访问顶部的github
GeneralTreeEntity
它界说了树形结构数据的通用树形,Id、Code、Name、Parent等 泛型TEntity是子节点的范例,由于是树,现实上也是父节点的范例,这种计划是方便未来模块利用方在实现自界说的树形结构时拿到的Parent树形和Children树形,是他们本身界说的范例 主键Id属性,我定死了long范例,其实也可以利用泛型的TKey,思来想去简朴起见直接定死吧
public class GeneralTreeEntity : GeneralTreeEntity
为了提供我们默认实现的“通用字典”功能,我们界说一个默认的子类GeneralTreeEntity,未来体系中那些简朴的数据可以直接利用它 IsSysDefine表现此节点是否是体系预界说的,未来不允许删除 IsTree是否是树形,未来大概会用到,因为某些下拉框数据大概不须要多层次的,好比:民族,学历
六、范畴服务
按套路我们提供一个抽象的范畴服务Manager类,和一个为了实现“通用字典”功能的默认实现
public abstract class GeneralTreeManager : DomainService where TEntity : GeneralTreeEntity
它的主要职责总体计划也说了一嘴,完成crud和move移动操纵,难点是处置惩罚code的自动天生,尤其是移动节点时,节点原来位置之后的别的节点及厥子女节点、目的节点之后的别的节点及厥子女节点的code的天生 内部对数据的操纵直接注入IRepository,因此按abp的套路,默认环境下利用EF时,调用方只须要在他的DBContext中顶一个DBSet就可以了
public class GeneralTreeManager : GeneralTreeManager
实现“通用数据字典”的默认范畴服类,因为焦点功能父类根本都完成了。所以险些没代码
七、应用服务
按套路一个抽象类,一个默认实现类,内部焦点操纵是上面提供的Manager来完成的,应用服务主要是出去权限和dto之间的转换
public class GeneralTreeAppServiceBase< TEntity, TDto, TEditDto> : ApplicationService, IGeneralTreeAppServiceBase where TEntity : GeneralTreeEntity where TDto : GeneralTreeGetTreeNodeBaseDto, new() where TEditDto : GeneralTreeNodeEditBaseDto
另外它提供了一些通用方法,一个树形数据通常在3个地方呗利用,以产物分类为例,在产物分类的管理页面、在产物的搜刮栏应该提供产物种别的选择、在产物编辑页面应该有个下拉框选择当前产物所属种别,别的树形数据都有雷同的场景,因此抽象的应用服务处置惩罚了这部门功能
public class GeneralTreeAppService : GeneralTreeAppServiceBase< GeneralTreeEntity, GeneralTreeDto, GeneralTreeEditDt, GeneralTreeManager>,IGeneralTreeAppService
按套路我们为“通用字典”提供了一个默认的实现类
应用服务中的DTO界说、应用服务接口我这里省略了,这是abp的通例套路,请看源码
八、abp干系套路:模块、当地化、权限、菜单
模块和当地化就不说了,abp的通例套路 由于我们提供了“通用字典”,默认环境下是可以直接用作你项目的,调用方完全可以按abp的套路在本身的模块中来设置权限和菜单,但是默认我们的模块也提供了,调用方完全可以在主机的PermissionProvicer和NavigationProvider的符合的位置设置权限和菜单。参考GeneralTreeModuleConfig源码
九、总结
abp本身提供了模块化方式,如果运用得当我们的体系可以由许多小模块构成,未来更容易维护、升级和复用 就好比我们目条件供的通用树,如果你利用的是abp,那么完全可以拿去就用,雷同的“通用附件”模块,因为我们的多个体系大概同一个体系都大概会用到附件的功能,随处复制代码是下下策。
|