博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于DDD的.NET开发框架 - ABP初探
阅读量:6207 次
发布时间:2019-06-21

本文共 7896 字,大约阅读时间需要 26 分钟。

ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称。

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

ABP的官方网站:

ABP官方文档:

Github上的开源项目:

一、基本概念

ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称。

ABP是土耳其的一位架构师hikalkan开发的,现在又加入一个ismcagdas开发者。

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

ABP的官方网站:

Github上的开源项目:

ABP官方文档:

强烈建议从事.NET的程序员学习下。

二、技术点

1、服务端

基于最新的.NET技术 (目前是ASP.NET MVC 5、Web API 2、C# 5.0,在ASP.NET 5正式发布后会升级)

实现领域驱动设计(实体、仓储、领域服务、领域事件、应用服务、数据传输对象,工作单元等)

实现分层体系结构(领域层,应用层,展现层和基础设施层)

提供了一个基础架构来开发可重用可配置的模块

集成一些最流行的开源框架/库,也许有些是你正在使用的。

提供了一个基础架构让我们很方便地使用依赖注入(使用Castle Windsor作为依赖注入的容器,为什么没有用autofac??)

提供Repository仓储模式支持不同的ORM(已实现Entity Framework 、NHibernate、MangoDb和内存数据库)

支持并实现数据库迁移(EF 的 Code first)

模块化开发(每个模块有独立的EF DbContext,可单独指定数据库)

包括一个简单的和灵活的多语言/本地化系统

包括一个 EventBus来实现服务器端全局的领域事件

统一的异常处理(应用层几乎不需要处理自己写异常处理代码)

数据有效性验证(Asp.NET MVC只能做到Action方法的参数验证,ABP实现了Application层方法的参数有效性验证)

通过Application Services自动创建Web Api层(不需要写ApiController层了)

提供基类和帮助类让我们方便地实现一些常见的任务

使用“约定优于配置原则”

2、客户端

Bootstrap、Less、AngularJs、jQuery、Modernizr和其他JS库: jQuery.validate、jQuery.form、jQuery.blockUI、json2

为单页面应用程序(AngularJs、Durandaljs)和多页面应用程序(Bootstrap+Jquery)提供了项目模板。

自动创建Javascript 的代理层来更方便使用Web Api

封装一些Javascript 函数,更方便地使用ajax、消息框、通知组件、忙状态的遮罩层等等

3、zero模块

身份验证与授权管理(通过ASP.NET Identity实现的)

用户&角色管理

系统设置存取管理(系统级、租户级、用户级,作用范围自动管理)

审计日志(自动记录每一次接口的调用者和参数)

三、从ABP官网获取模版

ABP模版地址:http://www.aspnetboilerplate.com/Templates

1、选择选择MPA,因为AngularJs或DurandalJs不太懂;

2、选择ORM框架(Entity Framework或NHibernate)我选择EF;

3、zero模块先不要选择

4、起个名字,我起的FirstABP

点击“CREATE MY PROJECT”下载一个zip压缩文件,用vs2013打开如下结构:

打开每个项目里引用了Abp组件和其他第三方组件,需要Nuget重新引用下,

生成下看看还有没有错误,然后把FirstABP.Web设为起始项目,F5

四、简单Demo

1、在FirstABP.Core 新建People文件夹,然后建一个Person实体

using Abp.Domain.Entities;namespace FirstABP.People{    public class Person : Entity    {        public virtual string Name { get; set; }        public virtual int? Age { get; set; }    }}

实体继承Abp.Domain.Entities.Entity基类,默认会有一个int类型自增的Id,如果想用其他类型可以指定,例如Abp.Domain.Entities.Entity<string>

2、把新建的Person实体类加入添加到IDbSet

在FirstABP.EntityFramework类库EntityFramework文件夹下的FirstABPDbContext文件里面

using System.Data.Entity;using Abp.EntityFramework;using FirstABP.People;namespace FirstABP.EntityFramework{    public class FirstABPDbContext : AbpDbContext    {        //TODO: Define an IDbSet for each Entity...        public virtual IDbSet
Person { get; set; } //Example: //public virtual IDbSet
Users { get; set; } /* NOTE: * Setting "Default" to base class helps us when working migration commands on Package Manager Console. * But it may cause problems when working Migrate.exe of EF. If you will apply migrations on command line, do not * pass connection string name to base classes. ABP works either way. */ public FirstABPDbContext() : base("Default") { } /* NOTE: * This constructor is used by ABP to pass connection string defined in FirstABPDataModule.PreInitialize. * Notice that, actually you will not directly create an instance of FirstABPDbContext since ABP automatically handles it. */ public FirstABPDbContext(string nameOrConnectionString) : base(nameOrConnectionString) { } }}

3、Database Migrations创建库和表

FirstABP.Web的webconfig,自动创建FirstABP数据库

修改SimpleTaskSystem.EntityFramework项目下Migrations文件夹下的Configuration.cs文件

using System.Data.Entity.Migrations;using FirstABP.People;namespace FirstABP.Migrations{    internal sealed class Configuration : DbMigrationsConfiguration
{ public Configuration() { AutomaticMigrationsEnabled = false; ContextKey = "FirstABP"; } protected override void Seed(FirstABP.EntityFramework.FirstABPDbContext context) { // This method will be called every time after migrating to the latest version. // You can add any seed data here... context.Person.AddOrUpdate(p => p.Name, new Person { Name = "Joye.NET",Age=25 }, new Person { Name = "Jerry.Core",Age=25 }, new Person { Name = "longhao",Age=25 }, new Person { Name = "xmm",Age=25 }); } }}

通过  工具 -> Nuget程序包管理器 - > 程序包管理器控制台, 默认项目需要选中FirstABP.EntityFramework,Add-Migration “InitialCreate” 创建

Migrations文件夹下生成一个201605170608193_InitialCreate.cs文件

namespace FirstABP.Migrations{    using System;    using System.Data.Entity.Migrations;        public partial class InitialCreate : DbMigration    {        public override void Up()        {            CreateTable(                "dbo.People",                c => new                    {                        Id = c.Int(nullable: false, identity: true),                        Name = c.String(),                        Age = c.Int(),                    })                .PrimaryKey(t => t.Id);                    }                public override void Down()        {            DropTable("dbo.People");        }    }}

继续执行“Update-Database”,会自动在数据库创建相应的数据表:

 

如果出现下图的问题,可能是Nuget版本太低,需要升级下,

 4、定义仓储接口

FirstABP.Core类库的people下新建IPersonRepository.cs

using System;using System.Collections.Generic;using Abp.Domain.Repositories;namespace FirstABP.People{    public interface IPersonRepository : IRepository
{ List
GetPersons(); }}

5、实现仓储接口

FirstABP.EntityFramework类库EntityFramework下的Repositories文件建PersonRepository.cs文件

using System;using System.Collections.Generic;using System.Linq;using Abp.EntityFramework;using FirstABP.People;namespace FirstABP.EntityFramework.Repositories{    public class PersonRepository : FirstABPRepositoryBase
,IPersonRepository { public PersonRepository(IDbContextProvider
dbContextProvider) : base(dbContextProvider) { } public List
GetPersons() { //在仓储方法中,不用处理数据库连接、DbContext和数据事务,ABP框架会自动处理。 //GetAll() 返回一个 IQueryable
接口类型 var query = GetAll(); return query.OrderByDescending(p=>p.Id).ToList(); } }}

6、创建领域服务(FirstABP.Application)

接口

using Abp.Application.Services;using FirstABP.People.DTO;namespace FirstABP.People{    public interface IPersonService : IApplicationService    {        GetAllPeopleOutput GetPersons();    }}

实现:

using System.Collections.Generic;using Abp.Application.Services;using AutoMapper;using FirstABP.People.DTO;namespace FirstABP.People{    public class PersonService : ApplicationService, IPersonService    {        private readonly IPersonRepository  _personRepository;        ///         /// 构造函数自动注入        ///         ///         public PersonService(IPersonRepository personRepository)        {            _personRepository = personRepository;        }        public GetAllPeopleOutput GetPersons()        {            var persons = _personRepository.GetPersons();            //用AutoMapper自动将List
转换成List
return new GetAllPeopleOutput { People = Mapper.Map
>(persons) }; } }}

7、在web获取调用

代码:

using System.Web.Mvc;using FirstABP.People;namespace FirstABP.Web.Controllers{    public class HomeController : FirstABPControllerBase    {        private readonly IPersonService _personService;        public HomeController(IPersonService personService)        {            _personService = personService;        }        public ActionResult Index()        {            //获取列表            var p = _personService.GetPersons();            return View("~/App/Main/views/layout/layout.cshtml"); //Layout of the angular application.        }    }}

运行结果:

最后看看新增了那些代码:

代码下载:https://yunpan.cn/cSwC9CbNtDMFt  访问密码 788c

深入学习推荐到

阳铭系列教程:

tkb至简系列教程:

转载地址:http://rfzja.baihongyu.com/

你可能感兴趣的文章
Python函数积累
查看>>
洛谷P1605:迷宫(DFS)
查看>>
jq挑战30天——打字机效果+小程序
查看>>
正则表达式怎样匹配 不包含特定字符串的字符串
查看>>
bzoj 2296: 【POJ Challenge】随机种子
查看>>
MPU和MCU的区别和选择
查看>>
js call
查看>>
apply和call用法
查看>>
学习笔记之-------UIScrollView 基本用法 代理使用
查看>>
如何理解运维
查看>>
Dom学习笔记
查看>>
JAVA流程控制学习总结
查看>>
配置yum,nc,telnet
查看>>
nib和xib的区别
查看>>
== 和 is 的区别
查看>>
Apple Swift编程语言新手教程
查看>>
linux服务器加入windows域时报错Ticket expired
查看>>
2018年,牛客网小白月赛5
查看>>
sql 锁
查看>>
生死相依:说说JQuery中die()、live()详解[翻译]
查看>>