• DDD的ABP开发框架


    基于DDD的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

    强烈建议从事.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> Person { get; 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"/>
      </connectionStrings>

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

    复制代码
    using System.Data.Entity.Migrations;
    using FirstABP.People;
    
    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 },
                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<Person,Int32>
        {
            List<Person> 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<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;
    
    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;
    
            /// <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;
    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

    深入学习推荐到

    阳铭系列教程:http://www.cnblogs.com/mienreal/p/4528470.html

    tkb至简系列教程:http://www.cnblogs.com/farb/p/ABPTheory.html

  • 相关阅读:
    POJ 3140 Contestants Division (树dp)
    POJ 3107 Godfather (树重心)
    POJ 1655 Balancing Act (树的重心)
    HDU 3534 Tree (经典树形dp)
    HDU 1561 The more, The Better (树形dp)
    HDU 1011 Starship Troopers (树dp)
    Light oj 1085
    Light oj 1013
    Light oj 1134
    FZU 2224 An exciting GCD problem(GCD种类预处理+树状数组维护)同hdu5869
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5503992.html
Copyright © 2020-2023  润新知