当前位置:文档之家› ABP框架模板开发手册

ABP框架模板开发手册

ABP框架模板开发手册杭州蒙特信息技术有限公司2018年1月目录1ABP框架介绍 (3)1.1ABP简介 (3)1.2ABP多层结构 (3)1.3ABP环境 (5)1.4开发环境 (5)2搭建网站 (5)2.1获取源码 (5)2.2搭建数据库 (6)2.3搭建站点 (8)3模块开发 (9)3.1领域层 (9)3.2应用层 (18)4后台页面 (22)5前台页面 (27)6后台配置....................................................................................................错误!未定义书签。

1ABP框架介绍1.1ABP简介我们总是对不同的需求开发不同的应用。

但至少在某些层面上,一次又一次地重复实现通用的和类似的功能。

如:授权,验证,异常处理,日志,本地化,数据库连接管理,设置管理,审核日志等功能。

所以我们创建架构和最佳实践,如分层和模块架构,DDD,依赖注入等,并尝试开发应用时基于一些约定。

由于所有这些是非常耗时而且很难单独创建并可适用于每个项目,许多公司创建自己的框架,他们用自己的框架能快速开发新应用而且不出错。

但不是所有的公司都是幸运的,大部分公司没有时间,预算和团队来开发好的框架。

他们甚至都没有可能创建一个框架,因为编写文档,培训开发人员和维护框架都是非常困难的。

Boilerplate (ABP) 是一个开源并且有丰富文档的应用框架,开发宗旨是:“为所有公司,所有开发人员,开发出一个通用框架!”,而且不只是一个框架,同时提供一个强大的基于DDD的构架模型和最佳实践。

1.2ABP多层结构一个应用的代码库的分层是一个广为接受的技术,用来减少复杂度和提高代码复用性。

ABP依照DDD理念来分层,在DDD里有4个基本的层:•表示层:为用户提供一个界面。

使用应用层来完成用户交互。

•应用层:表示层与领域层的媒介。

协调服务业对象执行指定的应用任务。

•领域层:包含业务对象和业务规则。

是整个应用的核心。

•基础层:提供支持更高层的通用技术。

一个基础层的典型例子是通过ORM框架实现与数据库的交互的仓储,或是实现发送邮件的邮件供应器。

也可以根据需要添加层,例如:•分布服务层:为远程客户端公开应用特性。

像 web API和WCF等。

这些都是以领域为核心的架构的通用层。

实现上可能有些细微的差别。

层和结构的预览如下ABP分层结构图如下1.3ABP环境前台环境MVC + Bootstrap后台环境Angular框架 + AdminLTE + Bootstrap基础环境.NET Framework 4.6.1 + EF1.4开发环境TypeScript:微软开发的自由和开源的编程语言,这是Javascript的超集;Web Compiler: A Visual Studio extension that compiles LESS, Sass, JSX, ES6 and CoffeeScript files;如何ABP的.NET框架是Core 2.0时则需要使用Visual Studio 20172搭建网站2.1获取源码第一步:通过SVN获取源码,源码下载之后Visual Studio打开源文件,第二步:用Visual Studio还原NuGet包如下图第三步:重新生成解决方案(检测项目正确性和完整性);2.2搭建数据库2.2.1配置信息第一步:创建空数据库database:database(数据库);uid:uid(用户名);pwd:ILwFjPFH8J(密码);第二步:修改配置文件g,配置网站数据库信息,更改ConnectionStrings的数据库连接字符串信息;database:数据库名 ,uid:用户名,pwd:密码;配置方法如下图2.2.2创建数据库第一步:打开程序包管理器控制台第二步:选择"EntityFramework"项目第三步:将Web项目设置为启动项第四步:执行命令创建数据库及表:Update-Database–Verbose第五步:执行完打开数据库管理器查看,如下图所示说明成功了到这里数据库的搭建工作完成。

2.3搭建站点第一步:重新生成解决方案第二步:将Mt.文件夹内的所有文件拷贝至网站的根目录下第三步:访问网站;后台网址:域名/B;默认账号:admin,密码:123qwe;开发者账号:mountor,密码:123qwe后台页面3模块开发3.1领域层领域层必须实现所有业务规则。

实体:展示数据和领域业务的操作。

通常地它们映射到数据库表。

仓储:类似于对象集合,用来获取和持久化实体到数据源(数据库)。

领域层定义了仓储,但不实现它们,由基础层来实现它们。

领域事件:定义领域里特定的事件,并触发和处理它们。

领域服务利用实体(及其它领域对象)实现那些不属于某个单独实体的业务规则。

工作单元:是一个管理数据库连接和事务的设计模式,跟踪实体变化并保存变化到数据存储。

领域层定义了它,但由基础层实现它。

这一层应该尽可能地独立于第三方类库。

3.1.1实体类实体是DDD一个核心的概念。

Eric Evans是这么描述的:“一个对象根本上不是按它的特性定义的,而是按一个线程的连续性和身份来定义”。

所以实体有一个id属性存入数据库中。

一个实体通常映射成关系型数据库的一个表。

继承FullAuditedEntity<Guid>:主键类型为Guid类型的全审计实体(软删除,记录删除时间和删除人员等信息)(必要)IPassivabile:信息状态接口(必要)IMustHaveTenant:必要性租户字段接口(必要)IMenuID:栏目ID接口(必要)INeedAuxiliaryId:辅助ID接口(辅助ID为long类字段)(必要)ILanguage:语言接口(必要)IAutoSynchronous:数据同步接口(非必要)ISynchronousSource:数据同步源接口(非必要)常量:字段长度限制规范:定义字段的限制3.1.2领域服务领域服务(或服务)用来执行领域操作和业务规则。

Eric Evans描述一个好的服务需要三个特点(在他的DDD书里):操作与领域概念(不是一个实体或值对象天生的一部分)相关。

接口要按照领域模型的其它元素来定义。

操作是无状态的。

与应用服务获取/返回DTO(数据传输对象)不同,领域服务获取/返回领域对象(如实体或值类型)。

领域服务可被应用服务或其它领域服务调用,但不直接被展现层(应用服务是针对它的)使用。

首先我们要为服务定义一个接口,接口继承IDomainService,接口中的服务包含创建、修改和删除有五个方法。

其次实现服务IDomainService 接口和DomainService 服务ABP定义了IDomainService接口,按约定所有的领域服务都要实现它,实现之后,领域服务被自动暂时的注册到依赖注入系统。

同样,领域服务(随意地)可以从DomainService类继承,因此它可以使用继承得来的日志、本地化、等属性。

即使不继承DomainService类,也可以在需要时注入它。

3.1.3定义模块权限授权系统使用IPermissionChecker来检查许可,虽然你用自己的方式实现它,不过在module-zero项目里已完全实现。

如果没有实现该接口,会使用NullPermissionChecker,它给每个人授予所有许可。

为每个操作定义的唯一许可必须得到授权,为使用许可要先定义一个,ABP是按模块化设计的,所以不同的模块可以拥有不同的许可,一个模块为了定义它的许可,应当创建一个继承AuthorizationProvider的类。

授权供应器示例如下:第一步:定义权限常量:第二步:定义权限许可第三步:定义许可中displayName的本地化(/Core/Localization/AppPermissions)IPermissionDefinitionContext拥有获取和创建许可的方法。

一个许可包含一些属性:Name:一个系统域内的唯一名称,用一个字符串常量,不用可变的字符串,是一个好的做法。

在分级里我们更喜欢用.(点)号来命名,但它不是必须的,你设置为你喜欢的名称,唯一的规则是一定要唯一。

DisplayName:一个本地化的用来之后在UI上显示许可的文本。

Description:一个本地化的用来之后在UI上显示许可描述的文本。

MultiTenancySides:在多租户应用里,许可可被租户或宿主使用,这是一个标记性的枚举,所以一个许可可同时被租户和宿主使用。

DependedFeature:用来表明一个对Feature(特色)的依赖,所以这个许可只有在满足Feature(特色)依赖时才会被允许。

一个许可可以有一个父许可和多个子许可,虽然这对于许可检查没有什么作用,但可能有助于在UI上组织许可。

第四步:创建一个授权供应器之后,我们应当在我们模块的预初始化方法里注册它,在Core/Common/中注册许可:3.1.4定义模块功能功能系统使用IFeatureValueStore来获取功能的值。

尽管你可以用自己的方式实现它,但在module-zero项目里已经完全实现。

如果它没有被实现,NullFeatureValueStore用来为所有功能返回null(这种情况下使用默认功能值)。

功能的值类型Boolean 类型:可以是“true”或“false”,一个这种类型的功能可以是启用或禁用(为一个版本或一个租户)。

Value 类型:可以是任意值,它保存和获取一个字符串,数字也保存成字符串。

第一步:定义功能常量:第二步:定义常量:在检查功能前,先要定义它,一个模块可通过继承FeatureProvider类来定义自己的功能一个功能定义要求至少两个属性:Name:一个唯一名称(字符串),这个功能的标志。

DefaultValue:一个默认值,当我们需要这个功能的值而又不能从当前租户取得时,我们需要一个默认值。

DisplayName:一个本地化的字符串,为用户显示这个功能的名称。

第三步:定义功能的displayName的本地化(/Core/Localization/AppFeatures)第四步:在创建一个功能供应器之后,我们应当在我们模块()的PreInitialize 方法里注册它(Core/Common/),如下所示:3.1.5更新数据库第一步:定义DbSet(Mt.)第二步:定义表名(Mt.yFramework.HkWebDbModelBuilderExtensions)第三步:执行命令更新数据库打开工具->NuGet包管理器->程序包管理器控制台,重新生成解决方案;然后将默认项目设置为EntityFrameworkCore;最后在控制台中输入Add-Migration“name”(name:不能用重复的名字可以使用“描述+日期”如:createNews)运行之后Migrations文件夹中2070_生成;第四步:更新数据库创建表;在程序包管理器控制台中运行Update-Database命令随后数据库就会新建了一个表3.2应用层应用层包含用于展示层的应用服务。

相关主题