基于DDD的.NET开发框架 - ABP初探
一、基本概念ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称。 ABP是土耳其的一位架构师hikalkan开发的,现在又加入一个ismcagdas开发者。
ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点,它旨在成为一个通用的WEB应用程序框架和项目模板。 ABP的官方网站:http://www.aspnetboilerplate.com Github上的开源项目:https://github.com/aspnetboilerplate ABP官方文档:http://www.aspnetboilerplate.com/Pages/Documents 强烈建议从事.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
四、简单Demo1、在FirstABP.Core 新建People文件夹,然后建一个Person实体 using Abp.Domain.Entities; namespace FirstABP.People { public class Person : Entity { virtual string Name { get; set; } int? Age { 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
{
class FirstABPDbContext : AbpDbContext
{
//TODO: Define an IDbSet for each Entity...
virtual IDbSet<Person> Person { set; }
Example:
public virtual IDbSet<User> 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数据库 <connectionStrings> add name="Default" connectionString="Server=localhost; Database=FirstABP; Trusted_Connection=True;" providerName="System.Data.SqlClient"/> </> 修改SimpleTaskSystem.EntityFramework项目下Migrations文件夹下的Configuration.cs文件 using System.Data.Entity.Migrations;
namespace FirstABP.Migrations
{
internal sealed class Configuration : DbMigrationsConfiguration<FirstABP.EntityFramework.FirstABPDbContext>
{
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 },0)">Jerry.Corelonghaoxmm25 });
}
}
}
通过 工具 -> Nuget程序包管理器 - > 程序包管理器控制台,默认项目需要选中FirstABP.EntityFramework,Add-Migration “InitialCreate”创建 Migrations文件夹下生成一个201605170608193_InitialCreate.cs文件 using System;
using System.Data.Entity.Migrations;
partial class InitialCreate : DbMigration
{
void Up()
{
CreateTable(
dbo.People",c => new
{
Id = c.Int(nullable: false,identity: true),Name = c.String(),Age = c.Int(),})
.PrimaryKey(t => t.Id);
}
void Down()
{
DropTable(");
}
}
}
继续执行“Update-Database”,会自动在数据库创建相应的数据表: 如果出现下图的问题,可能是Nuget版本太低,需要升级下,
4、定义仓储接口 FirstABP.Core类库的people下新建IPersonRepository.cs using System;
using System.Collections.Generic;
using Abp.Domain.Repositories;
interface IPersonRepository : IRepository<Person,Int32>
{
List<Person> GetPersons();
}
}
5、实现仓储接口 FirstABP.EntityFramework类库EntityFramework下的Repositories文件建PersonRepository.cs文件 using System.Linq;
namespace FirstABP.EntityFramework.Repositories
{
class PersonRepository : FirstABPRepositoryBase<Person,Int32>,IPersonRepository
{
public PersonRepository(IDbContextProvider<FirstABPDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public List<Person> GetPersons()
{
在仓储方法中,不用处理数据库连接、DbContext和数据事务,ABP框架会自动处理。
GetAll() 返回一个 IQueryable<T>接口类型
var query = GetAll();
return query.OrderByDescending(p=>p.Id).ToList();
}
}
}
6、创建领域服务(FirstABP.Application) 接口 using Abp.Application.Services;
using FirstABP.People.DTO;
interface IPersonService : IApplicationService
{
GetAllPeopleOutput GetPersons();
}
}
实现: using AutoMapper;
class PersonService : ApplicationService,IPersonService
{
private readonly IPersonRepository _personRepository;
/// <summary>
/// 构造函数自动注入
</summary>
<param name="personRepository"></param>
public PersonService(IPersonRepository personRepository)
{
_personRepository = personRepository;
}
public GetAllPeopleOutput GetPersons()
{
var persons = _personRepository.GetPersons();
用AutoMapper自动将List<Peopson>转换成List<PeopsonDto>
return new GetAllPeopleOutput
{
People = Mapper.Map<List<PersonDto>>(persons)
};
}
}
}
7、在web获取调用 代码: using System.Web.Mvc;
namespace FirstABP.Web.Controllers
{
class HomeController : FirstABPControllerBase
{
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 深入学习推荐到 阳铭系列教程:http://www.cnblogs.com/mienreal/p/4528470.html tkb至简系列教程:http://www.cnblogs.com/farb/p/ABPTheory.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |