浅谈ABP最佳实践

目录

  • ABP概念简述
  • ABP在【事务操作】上的简便性
  • ABP在【关联查询】上的“美”和“坑”
  • ABP的【参数验证】方式

ABP概念简述

ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称。它基于DDD的经典“分层架构”思想,开发了便捷的功能模块。

ABP在【事务操作】上的简便性

以一个最简单的学生选课为例,包含学生、课程、选课结果三个实体。

在学生选课过程中,当学生选课后,会进行两个操作:

1.增加学生选课记录。

2.增加课程班级人数。

这两个过程应该是事务型的操作,如果某个过程失败,则整个过程回滚。

在基于EntityFramework的框架中,通过可以使用TransactionScope实现

using (TransactionScope tran = new TransactionScope())
{
      ...
     tran.Complete();  
}

在ABP中实现如下,在AddSC()方法中不用任何关于事务的声明语句,使得整个过程的非常便捷。

这是因为ISCService继承了IApplicationService服务,IApplicationService即为“应用程序层”的基类。

ABP框架在“应用程序层”具有先天的事务性。所以在程序中,无须声明事务范围,实体更新后也不用saveChanges()。

“应用程序层”中的方法都被默认成了事务型操作。当方法成功执行后,会自动提交到数据库;当方法中的任意一个操作失败,整个操作都会自动回滚。

此外,如果某个“应用程序层”的方法对底层数据库只有查询操作,也可以给方法添加Attribute标签:[UnitOfWork(false)],来取消对某个方法的事务性限制。

 ABP在【关联查询】上的“美”和“坑”

 如果想查看某个学生所有的选课记录,在ABP中是很容易实现的。

 ABP通过延时加载来根据外键关系来查找,把关联查询更加简便和优雅(比EF便捷许多)

但是不可被美色蛊惑,此处有“暗坑”:被加载的List<Models.SC>具有延时加载特性,如果延时加载的对象在该工作单元内没有被调用,则对象会在方法结尾处自动被GC回收掉。

如果要在Api层调用GetClassByStudent方法,就必须要激活延时加载的对象。延时加载的对象只要被引用,就会自动被激活。如:

...
student.SCs= student.SCs;//引用延时加载对象,从而达到激活的目的
var classes = student.SCs;
...

 ABP【参数验证】方式

对某个方法的操作,对接收的参数的有效性往往需要校验,注入某些参数是必填的、某个数据的格式必须是合乎规范的等等。在.net mvc中继承Controller的类,可以通过实现接口IValidatableObject来验证mvc层的参数输入。但是无法验证非继承Controller的类。

在ABP框架中通过ICustomValidate和INormalize对所有类的参数的验证和规范化。

 

通过对参数有效性验证和规范化处理,使得输入参数在进入应用程序时就是符合要求的。让我们可以更专注“应用程序层”的业务逻辑。使代码更加规整,可读性也更高。

原文地址:https://www.cnblogs.com/zzPrince/p/6736494.html