手机版

ABP(现代ASP.NET模型开发框架)系列之二 ABP入门教程详细讲解

时间:2021-09-03 来源:互联网 编辑:宝哥软件园 浏览:

ABP是“ASP”的缩写。NET样板工程”。

ASP。NET样板是用最佳实践和流行技术开发现代WEB应用程序的新起点,旨在成为通用的WEB应用程序框架和项目模板。

ABP的官方网站:http://www.aspnetboilerplate.com

Github上ABP的开源项目:https://github.com/aspnetboilerplate

ABP的起源

“DRY——避免重复代码”是一个优秀的开发人员在开发软件时最重要的想法之一。我们在开发企业WEB应用时,都有一些类似的需求,比如登录页面、用户/角色管理、权限验证、数据有效性验证、多语言/本地化等等。一个高质量的大规模软件会用到一些最佳实践,比如分层架构、领域驱动设计、依赖注入等等。我们也可以使用诸如ORM、数据库迁移和日志等工具。

从头开始创建一个企业应用程序是很繁琐的,因为许多常见的基础工作需要重复完成。很多公司都在开发自己的应用框架,以便在不同的项目中重用,然后基于这个框架开发一些新的功能。但并不是每个公司都有这样的实力。如果我们可以分享更多,也许我们可以避免在每个公司或项目中重复编写类似的代码。作者将该项目命名为“ASP。NET样板”,希望它能成为开发通用企业WEB应用的新起点,并直接使用ABP作为项目模板。

什么是ABP?

ABP是使用最佳实践的起点,也是新的现代Web应用程序最流行的工具。它可以用作通用应用程序的基本框架或项目模板。其职能包括:

服务器端:

根据最新的。NET技术(目前MVC 5,Web API 2,ASP.NET c# 5.0,ASP.NET 5正式发布后会升级),领域驱动设计(实体、仓库、领域服务、领域事件、应用服务、数据传输对象、工作单元等。)和分层架构(域层、应用层、表示层和基础设施层)提供了开发可重用和可配置模块的基础设施提供了允许我们使用依赖注入(使用Windsor Castle作为依赖注入的容器)的基础设施提供Repository存储模式支持不同的ORM (Entity Framework、NHibernate、MangoDb和内存数据库)支持并实现数据库迁移的模块化开发(代码优先of EF)(每个模块都有独立的EF DbContext, 数据库可以单独指定)包括简单灵活的多语言/本地化系统,包括EventBus,实现服务器端全局域事件的统一异常处理(应用层几乎不需要处理自己编写的异常处理代码)。 数据有效性验证(Asp.NET MVC只能验证Action方法的参数,ABP实现应用层方法的参数有效性验证。)Web Api层是通过应用服务自动创建的(不需要编写ApiController层)。提供基类和帮助类可以让我们方便地实现一些常见的任务。使用“合同优于配置原则”客户端:

Bootstrap、Less、AngularJs、jQuery、Modernizr等Js库: jQuery.validate、jQuery.form、jQuery.blockUI、JS 2等。为单页应用程序(AngularJs、Durandaljs)和多页应用程序(Bootstrap Jquery)提供项目模板。自动创建Javascript的代理层,用Web Api封装一些Javascript函数,并使用ajax、消息框、通知组件、繁忙状态的屏蔽层等。除了ABP框架项目,还开发了一个名为“Zero”的模块,实现了以下功能:

认证和授权管理(由ASP.NET身份实现)用户角色管理系统设置访问管理(系统级、租户级、用户级、范围自动管理)审核日志(自动记录调用方和每个接口的参数)ABP不是什么?

ABP为最佳实践提供了一个应用程序开发模型。它有基本的类、接口和工具,这使得我们很容易构建可维护的大规模应用程序。

然而:

它不是RAD工具之一,RAD工具的目的是不用编码就能创建应用程序。相反,ABP提供了编码最佳实践。

它不是代码生成工具。虽然它有一些在运行时构建动态代码的功能,但它不能生成代码。

它不是一个综合框架。相反,它使用流行的工具/库来完成特定的任务(例如,使用EF作为ORM,使用Log4Net作为日志记录,使用Windsor Castle作为依赖注入容器,使用AngularJs作为SPA框架)。

就我使用ABP几个月的经验来看,虽然ABP不是RAD,但是用它开发项目肯定比传统的三层架构快很多。

虽然ABP不是代码生成工具,但是它让我们项目的代码更加简洁、规范,有利于代码生成工具的使用。

我用的是VS2013的Scaffolder T4开发的代码生成器,可以根据领域对象的UML类图自动生成所有前端代码和数据库。简单的凝乳模块几乎不需要编写代码,业务逻辑复杂的模块主要可以补充领域级代码。这样,我们可以花更多的时间在领域模型的设计上,减少编写代码的时间。

下面是原作者“简单任务系统”的一个例子,演示如何使用ABP开发项目

从模板创建一个空的web应用程序

ABP为新项目提供了一个启动模板(虽然可以手动创建项目并从nuget获取ABP包,但模板方法更简单)。

前往www.aspnetboilerplate.com/Templates,从模板创建您的应用程序。

可以选择SPA(AngularJs或DurandalJs)或MPA(经典多页应用)。可以选择实体框架或者NHibernate作为ORM框架。

这里我们选择AngularJs和Entity Framework,填写项目名称“SimpleTaskSystem”,点击“CREATE MY PROJECT”按钮下载一个zip压缩包,解压得到VS2013的解决方案。那个。使用的. NET版本是4.5.1。

Abp组件和其他第三方组件在每个项目中都有引用,需要从Nuget下载。

黄色感叹号图标表示该组件不在本地文件夹中,需要从Nuget还原。操作如下:

要使项目运行,您必须创建一个数据库。此模板假设您使用的是SQL2008或更高版本。当然,它可以很容易地被其他关系数据库取代。

打开网络。查看和配置链接字符串的配置文件:

添加名称='默认'连接字符串='服务器=本地主机;数据库=SimpleTaskSystemDb“可信连接=真;”/(稍后使用EF的Code first数据迁移时,将在SQL Server数据库中自动创建一个名为SimpleTaskSystemDb的数据库。)

这样,项目就做好了好运的准备!打开VS2013并按F5:

这个简单的任务系统程序将逐步实现

创建实体

在核心项目中编写实体类,因为实体是域层的一部分。

一个简单的应用场景:创建一些任务并分配给人们。我们需要两个实体,任务和人。

任务实体有几个属性:描述、创建时间、任务状态和引用人员的可选导航属性(已分配人员)。

公共类任务:实体长{[外键('分配的人员id ')]公共虚拟人已分配人员{获取设置;}公共虚拟int?AssignedPersonId { get设置;}公共虚拟字符串描述{ get设置;}公共虚拟日期时间创建时间{获取设置;}公共虚拟TaskState状态{获取设置;}公共任务(){ CreationTime=DateTime .现在;状态=任务状态。主动;} }人实体更简单,只定义了一个名字属性:

公共类人员:实体{公共虚拟字符串名称{ get设置;}}在雄激素结合蛋白框架中,有一个实体基类,它有一个身份属性。因为工作类继承自实体龙,所以它有一个长的类型的身份证。人类有一个(同国际组织)国际组织类型的Id,因为(同国际组织)国际组织类型是实体基类身份的默认类型,没有特别指定类型时,实体的身份就是(同国际组织)国际组织类型。

创建DbContext

使用EntityFramework需要先定义DbContext类,ABP的模板已经创建了DbContext文件,我们只需要把工作和人类添加到IDbSet,请看代码:

公共类SimpleTaskSystemDbContext : AbpDbContext {公共虚拟IDbSetTask任务{ get设置;}公共虚拟IDbSetPerson人{ get设置;}公共SimpleTaskSystemDbContext(): base(' Default '){ }公共SimpleTaskSystemDbContext(字符串名称或连接字符串):底座(名称或连接字符串){ }}通过数据库迁移创建数据库表

我们使用EntityFramework的代码优先模式创建数据库架构ABP。模板生成的项目已经默认开启了数据迁移功能,我们修改简单任务系统.EntityFramework项目下迁移文件夹下的Configuration.cs文件:

内部密封类配置:数据库迁移配置简单任务系统.EntityFramework。SimpleTaskSystemDbContext { public Configuration(){ automaticmigratingenabled=false;}受保护的覆盖无效种子(简单任务系统.EntityFramework。SimpleTaskSystemDbContext上下文){上下文.人们。添加日期(p=p .姓名,新人员{姓名='艾萨克阿西莫夫},新人{姓名='托马斯莫尔' },新人{姓名='乔治奥威尔' },新人{姓名='道格拉斯亚当斯' });}}在VS2013底部的"程序包管理器控制台"窗口中,选择默认项目并执行命令"添加-迁移初始创建"

会在迁移文件夹下生成一个xxxx-InitialCreate.cs文件,内容如下:

公共分部类初始创建: DbMigration { public override void Up(){ create table(' dbo .StsPeople ',c=new { Id=c . Int(可空: false,可标识: true),Name=c.String(),}).主键(t=t . Id);CreateTable('dbo .StsTasks ',c=new { Id=c . Long(可空: false,标识: true),AssignedPersonId=c . Int(),Description=c.String(),创建时间=c . DateTime(可空: false),State=c . Byte(可空: false),}).主键ForeignKey('dbo ' .' StsPeople ',t=t.AssignedPersonId).索引(t=t .指定人员id);}公共覆盖void Down() { DropForeignKey('dbo .StsTasks ',' AssignedPersonId ',' dbo .StsPeople’);DropIndex('dbo .StsTasks ',new[]{ '分配的personaid ' });DropTable('dbo .ststaks’);DropTable('dbo .StsPeople’);}}然后继续在"程序包管理器控制台"执行"更新-数据库",会自动在数据库创建相应的数据表:

预防性维护更新-数据库数据库显示如下:

(以后修改了实体,可以再次执行添加-迁移和更新-数据库,就能很轻松的让数据库结构与实体类的同步)

定义仓储接口

通过仓储模式,可以更好把业务代码与数据库操作代码更好的分离,可以针对不同的数据库有不同的实现类,而业务代码不需要修改。

定义仓储接口的代码写到核心项目中,因为仓储接口是领域层的一部分。

我们先定义工作的仓储接口:

公共接口ITaskRepository : irepostory task,long{它继承自雄激素结合蛋白框架中的我的立场泛型接口。

在我的立场中已经定义了常用的增删改查方法:

所以ITaskRepository默认就有了上面那些方法。可以再加上它独有的方法GetAllWithPeople(.)。

不需要为人类创建一个仓储类,因为默认的方法已经够用了ABP。提供了一种注入通用仓储的方式,将在后面"创建应用服务"一节的TaskAppService类中看到。

实现仓储类

我们将在EntityFramework项目中实现上面定义的ITaskRepository仓储接口。

通过模板建立的项目已经定义了一个仓储基类:SimpleTaskSystemRepositoryBase(这是一种比较好的实践,因为以后可以在这个基类中添加通用的方法)。

公共类任务存储库: simpletasksystorpowerbasettask,long,ITaskRepository { public list task getallwithoupeoples(int?已分配个人标识,任务状态?状态){ //在仓储方法中,不用处理数据库连接、DbContext和数据事务,ABP框架会自动处理var query=GetAll();//GetAll()返回一个IQueryableT接口类型//添加一些在哪里条件if (assignedPersonId .HasValue) { query=query .其中(任务=任务。已分配人员。标识==已分配人员标识。价值);} if (state .HasValue) { query=query .其中(任务=任务. state==state);}返回查询orderby降序(任务=任务创造时间).包含(任务=任务。被指派的人)。to list();}}TaskRepository继承自简单任务系统存储库并且实现了上面定义的ITaskRepository接口。

创建应用服务(应用服务)

在应用项目中定义应用服务。首先定义工作的应用服务层的接口:

公共接口ITaskAppService : IApplicationService { gettasksoutput GetTasks(GetTasksInput输入);void UpdateTask(更新任务输入);void CreateTask(CreateTaskInput输入);}ITaskAppService继承自应用服务自动为这个类提供一些功能特性(比如依赖注入和参数有效性验证)。

然后,我们写TaskAppService类来实现ITaskAppService接口:

公共类tasapp service : ApplicationService,ITaskAppService { private readonly ITaskRepository _ task repository;私有只读IRepositoryPerson _ personal存储库;///摘要///构造函数自动注入我们所需要的类或接口////摘要公共任务应用服务(ITaskRepository taskRepository,irepositorypersonrepository){ _ task repository=task repository;_个人存储库=个人存储库;} public gettasksoutput GetTasks(GetTasksInput输入){ //调用工作仓储的特定方法getall with people var tasks=_ task资源库.GetAllWithPeople(输入。已分配个人标识,输入。国家);//用自动映射器自动将列表任务转换成列表任务返回新的GetTasksOutput { Tasks=Mapper .MapListTaskDto(任务)};} public void UpdateTask(更新任务输入){ //可以直接伐木工,它在应用服务基类中定义的伐木工。信息('更新输入: '输入的任务);//通过仓储基类的通用方法去拿,获取指定身份的工作实体对象var task=_taskRepository .获取(输入. TaskID);//修改工作实体的属性值如果(输入国家。哈希值){任务.状态=输入。状态。价值;}如果(输入指定的个人id。HasVaLue){ 0任务分配的人员=_人员存储库.加载(输入。已分配的个人标识值);} //我们都不需要调用更新方法//因为应用服务层的方法默认开启了工作单元模式(工作单位)//ABP框架会工作单元完成时自动保存对实体的所有更改,除非有异常抛出。有异常时会自动回滚,因为工作单元默认开启数据库事务。公共空间创建任务(创建任务输入输入){ Logger .信息('为输入创建任务' : '输入);//通过输入参数,创建一个新的工作实体定义变量任务=新任务{描述=输入。描述};如果(输入指定的个人id。HasVaLue){ 0任务AssignedPersonId=输入。已分配的个人标识值;} //调用仓储基类的插入方法把实体保存到数据库中_任务存储库.插入(任务);}}TaskAppService使用仓储进行数据库操作,它通往构造函数注入仓储对象的引用。

数据验证

如果应用服务(应用服务)方法的参数对象实现了输入到或IValidate接口,ABP会自动进行参数有效性验证。

创建任务方法有一个创建任务输入参数,定义如下:

公共类createtaskenput : iinputo { public int?AssignedPersonId { get设置;}[必选]公共字符串描述{获取设置;} }描述属性通过注解指定它是必填项。也可以使用其他数据注释特性。

如果你想使用自定义验证,你可以实现ICustomValidate接口:

公共类UpdateTaskInput : IInputDto,ICustomValidate {[范围(1,长.MaxValue)])公共长TaskId { get设置;} public int?AssignedPersonId { get设置;} public TaskState?状态{获取设置;} public void AddValidationErrors(列表验证结果结果){如果(分配的人员id==空状态==空){结果.添加(新的验证结果(' AssignedPersonId和状态不能同时为空!',new[]{ '分配的personaid ',' State ' });} }}你可以在添加验证错误方法中写自定义验证的代码。

创建Web Api服务

雄激素结合蛋白可以非常轻松地把应用服务的公众的方法发布成Web Api接口,可以供客户端通过创建交互式、快速动态网页应用的网页开发技术调用。

DynamicApiControllerBuilder .对于应用服务(程序集GetAssembly(类型为(SimpleTaskSystemApplicationModule)),' tasksystem ').build();SimpleTaskSystemApplicationModule这个程序集中所有继承了应用服务接口的类,都会自动创建相应的ApiController,其中的公开方法,就会转换成WebApi接口方法。

可以通过http://XXX/API/服务/任务系统/任务/获取任务这样的路由地址进行调用。

通过上面的案例,大致介绍了领域层、基础设施层、应用服务层的用法。

现在可以直接调用ASP.NET MVC控制器的Action方法中的应用服务的方法。

如果使用SPA单页编程,可以通过ajax(通过创建动态Web Api)直接在客户端调用对应的Application Service方法。

摘要

以上是边肖推出的第二个ABP(现代ASP.NET模型开发框架)系列。希望对大家有帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!

版权声明:ABP(现代ASP.NET模型开发框架)系列之二 ABP入门教程详细讲解是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。