介绍

我们基于不同的需求创建不同的应用,但却在一次又一次地实现相同或相似的结构。至少在某种程度上,授权、验证、异常处理、日志、本地化、数据库连接管理、配置管理、审计日志属于通用的结构

另外我们总是在构建体系结构和最佳实践,比如分层和模块化架构,领域驱动设计,依赖注入等等,同时也在尝试基于惯例来开发应用。这些都是非常耗时且难于对每个项目独立构建。所以许多公司会构建自己的框架,他们用这些框架更快速、更少BUG地开发新应用。但是并不是所有公司都这么幸运,他们大部分都没有时间、预算、团队来开发这类框架。即便他们可能做出一个框架来,写文档,培训开发者以及维护也是很难的。

ASP.NET Boilerplate (ABP) 是一个开源的、文档完善的应用框架,基于“为所有公司和所有开发者开发一个通用的框架”这一目标,它不仅仅是一个框架,也是一个基于DDD和最佳实践的健壮的体系模型。

由一个简单类来探究ABP的优势

public class TaskAppService : ApplicationService, ITaskAppService
{
    private readonly IRepository<Task> _taskRepository;

    public TaskAppService(IRepository<Task> taskRepository)
    {
        _taskRepository = taskRepository;
    }

    [AbpAuthorize(MyPermissions.UpdatingTasks)]
    public async Task UpdateTask(UpdateTaskInput input)
    {
        Logger.Info("Updating a task for input: " + input);

        var task = await _taskRepository.FirstOrDefaultAsync(input.TaskId);
        if (task == null)
        {
            throw new UserFriendlyException(L("CouldNotFoundTheTaskMessage"));
        }

        input.MapTo(task);
    }
}

UpdateTask是一个简单的应用服务类的方法。在DDD中一个应用服务,会直接被表现层调用来实现应用的用例,比如它可能会被JavaScript通过AJAX调用。

总结这个类中的一些便利实现:

依赖注入 Dependency Injection

ABP使用并提供了一个健壮而又惯例式的DI基础设施。因为上面的类是一个应用服务,所以它会按照惯例约定临时地(每个请求创建一次)注册到DI容器中。它也简单地注入了所有依赖(本例中注入了IRepository)。 

仓储 Repository

ABP可以为每一个实体创建一个默认的仓储(本例中是IRepository<Task>)。默认的仓储有许多有用的方法,如本例中的 FirstOrDefault。我们也可以根据自己的需求很容易地扩展这个默认仓储。仓储抽象了DBMS(数据库管理系统)和ORMs(对象关系映射),并简化了数据的访问逻辑。

授权 Authorization

ABP可以检查权限。如果当前的用户没有“updating task”权限或者没登录,那么他对UpdateTask方法的访问会被阻止。声明式的特性简化了授权方式,但其他的授权方法也一样可以使用。

验证 Validation

ABP会自动校验输入是否为null。它也基于标准的数据注解特性和自定义的验证规则验证输入对象的所有属性。如果请求不合法,那么它会抛出一个合适的验证异常。

审计日志 Audit Logging

基于惯例和配置为每个请求自动地保存 用户,浏览器,IP地址,调用服务,方法,参数,调用时间,执行时长和其他的一些信息。 

工作单元 Unit Of Work

在ABP中,每个应用服务方法默认地视作是一个工作单元。它会自动创建一个连接并在方法的开始位置开启一个事务。如果方法不报异常地顺利执行了,那么事务会提交,连接也会释放。即使该方法使用了不同的仓储或者方法,它们也全部都是原子的(事务的)。当事务提交时,实体的所有改变都会自动保存。因此,正如方法实现的那样,我们甚至都不需要调用“_repository.Update(task)”方法。

异常处理 Exception Handling

在一个使用了ABP框架的Web应用中,我们基本上不用处理异常。所有的异常都会默认自动处理。如果一个异常发生了,那么ABP会自动地记录它,然后返回给客户端一个合适的结果。比如,如果这是一个AJAX请求,那么它会返回一个JSON到客户端,指明发生了一个错误。本例中使用了一个UserFriendlyException,这样就隐藏了客户端实际的异常信息。它也能理解并处理客户端的错误,最后将合适的信息呈现给用户。

日志 Logging

就像看到的,我们使用基类中定义的Logger对象来记录日志。默认使用Log4Net,但这是可以改变和配置的。

本地化 Localization

主义到我们在抛出异常时使用了L方法,它会基于当前用户的文化自动进行本地化。当然,我们会在某些地方定义CouldNotFoundTheTaskMessage(视本地化文档的实现而定)。

自动映射 Auto Mapping

在最后一行代码,我们使用了ABP的MapTo扩展方法将输入对象的属性映射到实体属性。它使用了AutoMapper库来执行映射。因此,我们可以基于命名惯例轻易地将属性从一个对象上映射到另一个对象上。

自动Web API层 Dynamic Web API Layer

实际上,TaskAppService 是一个简单的类(甚至不需要从ApplicationService 继承)。我们一般会写一个Web API Controller包装器来将方法暴露给javascript客户端,ABP在运行时会自动完成这些。这样,我们可以从客户端直接使用应用服务方法。

动态Ajax代理 Dynamic Javascript AJAX Proxy

ABP创建了javascript代理方法,它们可以调用应用服务方法就像调用客户端的javascript方法一样简单。

在这么一个简单的类中,我们看到了ABP的优势。所有的这些任务正常情况下都是要花费很多时间的,但是所有的这些ABP自动帮我们完成了。

其他

除了上面例子中展示的, ABP还提供了一个健壮的基础设施和应用模型。下面是ABP的一下其他特征:

模块化 Modularity

Provides a strong infrastructure to build reusable modules.

数据过滤 Data Filters

Provides automatic data filtering to implement some patterns like soft-delete and multi-tenancy.

多租户 Multi Tenancy

It fully supports multi-tenancy, including single database or database per tenant architectures.

配置管理 Setting Management

Provides a strong infrastructure to get/change application, tenant and user level settings.

单元&集成测试 Unit & Integration Testing

It's built testability in mind. Also provides base classes to simplify unit & integration tests. See this article for more information.

更多特征,请阅读文档

启动模板

创建一个新的解决方案,创建层,安装nuget包,创建爱一个简单的布局和菜单……,所有这些是非常耗时的。
ABP提供了一个预生成的启动模板,它让创建一个新的解决方案变得更加容易。模板支持SPA(单页应用)和MPA(多页应用)。而且,我们可以选择不同的ORM。

使用

ABP的源码已经推送到了Github 上,Nuget包也已经发布到了Nuget上。开始使用ABP最简单的方式就是使用ABP官网的模板创建项目,然后跟着文档来学习。

ABP文档 :Overall - Introduction的更多相关文章

  1. ABP文档笔记系列

    ABP文档笔记 - 模块系统 及 配置中心 ABP文档笔记 - 事件BUS ABP文档笔记 - 数据过滤 ABP文档笔记 - 规约 ABP文档笔记 - 配置.设置.版本.功能.权限 ABP文档笔记 - ...

  2. ABP文档 - Javascript Api - AJAX

    本节内容: AJAX操作相关问题 ABP的方式 AJAX 返回信息 处理错误 HTTP 状态码 WrapResult和DontWrapResult特性 Asp.net Mvc 控制器 Asp.net ...

  3. ABP文档 - EntityFramework 集成

    文档目录 本节内容: Nuget 包 DbContext 仓储 默认仓储 自定义仓储 特定的仓储基类 自定义仓储示例 仓储最佳实践 ABP可使用任何ORM框架,它已经内置了EntityFrame(以下 ...

  4. ABP文档 - SignalR 集成

    文档目录 本节内容: 简介 安装 服务端 客户端 连接确立 内置功能 通知 在线客户端 帕斯卡 vs 骆峰式 你的SignalR代码 简介 使用Abp.Web.SignalR nuget包,使基于应用 ...

  5. ABP文档 - 通知系统

    文档目录 本节内容: 简介 发送模式 通知类型 通知数据 通知重要性 关于通知持久化 订阅通知 发布通知 用户通知管理器 实时通知 客户端 通知存储 通知定义 简介 通知用来告知用户系统里特定的事件发 ...

  6. ABP文档 - Hangfire 集成

    文档目录 本节内容: 简介 集成 Hangfire 面板授权 简介 Hangfire是一个综合的后台作业管理器,可以在ABP里集成它替代默认的后台作业管理器,你可以为Hangfire使用相同的后台作业 ...

  7. ABP文档 - 后台作业和工作者

    文档目录 本节内容: 简介 后台作业 关于作业持久化 创建一个后台作业 在队列里添加一个新作业 默认的后台作业管理器 后台作业存储 配置 禁用作业执行 Hangfire 集成 后台工作者 创建一个后台 ...

  8. ABP文档 - Javascript Api

    文档目录 本节内容: AJAX Notification Message UI Block & Busy Event Bus Logging Other Utility Functions A ...

  9. ABP文档 - 导航

    文档目录 本节内容: 创建菜单 注册导航供应器 显示菜单 每个web应用都有一些菜单用来在页面/屏幕之间导航,ABP提供了一个通用的基础框架创建并显示菜单给用户. 创建菜单 一个应用可能由不同模块组成 ...

随机推荐

  1. python学习笔记(基础三:if else流程判断、while循环、for循环)

    if else流程判断 getpass在pycharm中无法使用,在命令行窗口中进入python环境可以使用. import getpassusername = input("usernam ...

  2. 【夯实PHP基础】PHP的反射机制

    本文地址 分享提纲: 1. 介绍 2. 具体例子 2.1 创建Persion类 2.2 反射过程 2.3 反射后使用 1. 介绍 -- PHP5添加了一项新的功能:Reflection.这个功能使得p ...

  3. Hibernate框架之Criteria查询 和注解(重点☆☆☆☆☆,难点☆☆☆)

    写好一篇博客,不是容易的事.原因是:你要给自己以后看的时候,还能看懂,最重要的是当别人看到你的博客文章的时候,也一样很清楚的明白你自己写的东西.其实这也是一种成就感!! 对于每一个知识点,要有必要的解 ...

  4. javascript 表单

    在HTML中,表单是由<form>元素来组成的.在js中,表单对应的则是HTMLFormElement类型.它和其他HTML元素一样具有相同的默认属性.下面是HTMLFormElement ...

  5. jasmine test 页面测试工具

    before((request, response) -> { response.header("Access-Control-Allow-Origin", "ht ...

  6. Nuclear开始

    为什么Nuclear 这里列举Nuclear在竞品中的优势: 借助浏览器本身的机制,无任何代码约定和入侵 放心使用HTML+CSS+JS observejs替代EventLoop.requestAni ...

  7. 开发属于自己的yeoman脚手架(generator-reactpackage)

    自从前后端开始分离之后,前端项目工程化也显得越来越重要了,之前写过一篇搭建基于Angular+Requirejs+Grunt的前端项目教程,有兴趣的可以点这里去看 但是有些项目可以使用这种方式,但有些 ...

  8. node.js xtemplate的使用实例

    工程下安装XTemplate并使用它的方法实例说明: 1.安装xtpl npm install xtpl xtemplate --save 2.在views目录添加test.xtpl文件,其内容为 t ...

  9. JAVA编程思想(第四版)学习笔记----11.10 Map

    之前学习的是Collection层次的List接口.List层次比较简单,除去与多线程安全相关的CoppyOnWriteArrayList<T>类,这一个类在集中涉及多线程相关知识时候再学 ...

  10. vim 中替换

    将80替换为10.0.0.19:80 :g/80/s//10.0.0.19:80/g