abp是一个开源应用程序框架,该项目是asp.net boilerplate web应用程序框架的下一代,专注于基于asp.net core的web应用程序开发,也支持开发控制台应用程序。

官方网站:
官方文档:

一、使用abp框架可以快速的搭建一个应用程序,仅需要几步即可完成:

1. 安装abp cli

abp cli是使用abp框架启动新解决方案的最快方法。如果没有安装abp cli,使用命令行窗口安装abp cli:

dotnet tool install -g volo.abp.cli

2. 在一个空文件夹中使用abp new命令创建您的项目:

abp new acme.bookstore

您可以使用不同级别的名称空间。例如bookstore,acme.bookstore或acme.retail.bookstore。

这样,就已经完成了一个应用程序的搭建。

然后我们只需要修改一下其他的配置即可运行应用程序,开发人员在这个架构的基础上就可以愉快的撸代码了。

然而,abp的学习才刚刚开始。abp放弃了原有mvc的架构,使用了模块化架构,支持微服务,根据ddd模式和原则设计和开发,为应用程序提供分层模型。对于没有微服务开发经验的程序员来说,学习abp难度比较大。下面我们开始从一个空的web解决方案,一步步搭建api接口服务。

二、用apb基础架构搭建一个用户中心api接口服务

开发环境:mac visual studio code
sdk:dotnet core 3.1

1. 首先我们创建一个文件夹lemon.usercenter,并在终端中打开该文件夹。

使用命令创建一个空的web方案:

dotnet new web -o lemon.usercenter.httpapi.hosting

2. 再使用命令创建其他类库方案:

创建api层
dotnet new classlib -o lemon.usercenter.httpapi
创建应用层
dotnet new classlib -o lemon.usercenter.application
创建领域层
dotnet new classlib -o lemon.usercenter.domain
创建基于entityframeworkcore的数据层
dotnet new classlib -o lemon.usercenter.entityframeworkcore

3. 把所有类库加入解决方案,然后类库间互相引用:

创建解决方案
dotnet new sln
所有类库加入解决方案
dotnet sln lemon.usercenter.sln add lemon.usercenter.httpapi.hosting/lemon.usercenter.httpapi.hosting.csproj
dotnet sln lemon.usercenter.sln add lemon.usercenter.httpapi/lemon.usercenter.httpapi.csproj
dotnet sln lemon.usercenter.sln add lemon.usercenter.application/lemon.usercenter.application.csproj
dotnet sln lemon.usercenter.sln add lemon.usercenter.domain/lemon.usercenter.domain.csproj
dotnet sln lemon.usercenter.sln add lemon.usercenter.entityframeworkcore/lemon.usercenter.entityframeworkcore.csproj
添加项目引用
dotnet add lemon.usercenter.httpapi.hosting/lemon.usercenter.httpapi.hosting.csproj reference lemon.usercenter.httpapi/lemon.usercenter.httpapi.csproj
dotnet add lemon.usercenter.httpapi.hosting/lemon.usercenter.httpapi.hosting.csproj reference lemon.usercenter.entityframeworkcore/lemon.usercenter.entityframeworkcore.csproj
dotnet add lemon.usercenter.httpapi/lemon.usercenter.httpapi.csproj reference lemon.usercenter.application/lemon.usercenter.application.csproj
dotnet add lemon.usercenter.application/lemon.usercenter.application.csproj reference lemon.usercenter.domain/lemon.usercenter.domain.csproj
dotnet add lemon.usercenter.entityframeworkcore/lemon.usercenter.entityframeworkcore.csproj reference lemon.usercenter.domain/lemon.usercenter.domain.csproj

4. 在领域层新增实体。

领域层添加volo.abp.identity.domain包引用:

dotnet add lemon.usercenter.domain/lemon.usercenter.domain.csproj package volo.abp.identity.domain

创建领域层模块类:

using volo.abp.identity;
using volo.abp.modularity;

namespace lemon.usercenter.domain
{
    [dependson(typeof(abpidentitydomainmodule))]
    public class usercenterdomainmodule : abpmodule
    {
        
    }
}

创建实体类:

using system;
using volo.abp.domain.entities;

namespace lemon.usercenter.domain
{
    public class userdata : entity<guid>
    {
        /// <summary>
        /// 账号
        /// </summary>
        /// <value>the account.</value>
        public string account { get; set; }

        /// <summary>
        /// 昵称
        /// </summary>
        /// <value>the name of the nike.</value>
        public string nickname { get; set; } = "";

        /// <summary>
        /// 头像
        /// </summary>
        /// <value>the head icon.</value>
        public string headicon { get; set; } = "";

        /// <summary>
        /// 手机号码
        /// </summary>
        /// <value>the mobile.</value>
        public string mobile { get; set; } = "";

        /// <summary>
        /// 电子邮箱
        /// </summary>
        /// <value>the email.</value>
        public string email { get; set; } = "";

        /// <summary>
        /// 删除注记
        /// </summary>
        /// <value><c>true</c> if deleted; otherwise, <c>false</c>.</value>
        public bool deleted { get; set; }
    }
}

5. 创建数据层

数据层添加引用:

dotnet add lemon.usercenter.entityframeworkcore/lemon.usercenter.entityframeworkcore.csproj package volo.abp.entityframeworkcore
dotnet add lemon.usercenter.entityframeworkcore/lemon.usercenter.entityframeworkcore.csproj package volo.abp.entityframeworkcore.postgresql
dotnet add lemon.usercenter.entityframeworkcore/lemon.usercenter.entityframeworkcore.csproj package microsoft.entityframeworkcore.design
dotnet add lemon.usercenter.entityframeworkcore/lemon.usercenter.entityframeworkcore.csproj package microsoft.entityframeworkcore
dotnet add lemon.usercenter.entityframeworkcore/lemon.usercenter.entityframeworkcore.csproj package microsoft.entityframeworkcore.relational

在这里我们使用的是postgresql数据库,所以引用了volo.abp.entityframeworkcore.postgresql,如果使用的是mysql,就要引用volo.abp.entityframeworkcore.mysql,如果使用的是sqlserver,就要引用volo.abp.entityframeworkcore.sqlserver。

加入usercenterdbcontext类:

using lemon.usercenter.domain;
using microsoft.entityframeworkcore;
using volo.abp.data;
using volo.abp.entityframeworkcore;

namespace lemon.usercenter.entityframeworkcore
{
    [connectionstringname("default")]
    public class usercenterdbcontext : abpdbcontext<usercenterdbcontext>
    {
        public dbset<userdata> userdata { get; set; }
        
        public usercenterdbcontext(dbcontextoptions<usercenterdbcontext> options)
            : base(options)
        {

        }

        protected override void onmodelcreating(modelbuilder builder)
        {
            base.onmodelcreating(builder);
        }

    }
}

加入usercenterdbcontextfactory类:

using system.io;
using microsoft.entityframeworkcore;
using microsoft.entityframeworkcore.design;
using microsoft.extensions.configuration;

namespace lemon.usercenter.entityframeworkcore
{
    public class usercenterdbcontextfactory: idesigntimedbcontextfactory<usercenterdbcontext>
    {
        public usercenterdbcontext createdbcontext(string[] args)
        {
            var configuration = buildconfiguration();

            var builder = new dbcontextoptionsbuilder<usercenterdbcontext>()
                .usenpgsql(configuration.getconnectionstring("default"));

            return new usercenterdbcontext(builder.options);
        }

        private static iconfigurationroot buildconfiguration()
        {
            var builder = new configurationbuilder()
                .setbasepath(directory.getcurrentdirectory())
                .addjsonfile("appsettings.json", optional: false);

            return builder.build();
        }
    }
}

加入appsettings.json配置,用于生成数据迁移代码:

{
    "connectionstrings": {
      "default": "server=127.0.0.1;port=5432;database=abp-samples-user-center;uid=postgres;pwd=123456"
    }
}

创建数据层模块类:

using lemon.usercenter.domain;
using microsoft.entityframeworkcore;
using microsoft.extensions.dependencyinjection;
using volo.abp.entityframeworkcore;
using volo.abp.entityframeworkcore.postgresql;
using volo.abp.modularity;

namespace lemon.usercenter.entityframeworkcore
{
    [dependson(typeof(usercenterdomainmodule),
        typeof(abpentityframeworkcoremodule),
        typeof(abpentityframeworkcorepostgresqlmodule))]
    public class usercenterentityframeworkcoremodule : abpmodule
    {
        public override void configureservices(serviceconfigurationcontext context)
        {
            context.services.addabpdbcontext<usercenterdbcontext>(options => {
                options.adddefaultrepositories(includeallentities: true);
            });

            configure<abpdbcontextoptions>(options =>
            {
                options.configure(ctx =>
                {
                    if (ctx.existingconnection != null)
                    {
                        ctx.dbcontextoptions.usenpgsql(ctx.existingconnection);
                    }
                    else
                    {
                        ctx.dbcontextoptions.usenpgsql(ctx.connectionstring);
                    }
                });
            });

            #region 自动迁移数据库

            context.services.buildserviceprovider().getservice<usercenterdbcontext>().database.migrate();

            #endregion 自动迁移数据库
        }
    }
}

生成数据迁移代码:

dotnet ef migrations add initialcreate --project lemon.usercenter.entityframeworkcore/lemon.usercenter.entityframeworkcore.csproj

在数据层下生成一个migrations文件夹,里面的代码就是数据迁移代码,执行以下命令即可在数据库中自动生成数据库表:

dotnet ef database update --project lemon.usercenter.entityframeworkcore/lemon.usercenter.entityframeworkcore.csproj

6. 在应用层实现具体业务逻辑

应用层添加volo.abp.identity.application应用:

dotnet add lemon.usercenter.application/lemon.usercenter.application.csproj package volo.abp.identity.application

创建应用层模块类:

using volo.abp.modularity;
using volo.abp.identity;

namespace lemon.usercenter.application
{
    [dependson(typeof(abpidentityapplicationmodule))]
    public class usercenterapplicationmodule : abpmodule
    {
        
    }
}

创建用户接口:

using system.threading.tasks;
using lemon.usercenter.domain;

namespace lemon.usercenter.application
{
    public interface iuserservice
    {
         task<userdata> create(userdata data);
    }
}

实现用户服务:

using system;
using system.threading.tasks;
using lemon.usercenter.domain;
using volo.abp.application.services;
using volo.abp.domain.repositories;

namespace lemon.usercenter.application
{
    public class userservice : applicationservice, iuserservice
    {
        private readonly irepository<userdata, guid> _repository;
        public userservice(irepository<userdata, guid> repository)
        {
            this._repository = repository;
        }

        public async task<userdata> create(userdata data)
        {
            return await _repository.insertasync(data);
        }
    }
}

7. 在api层实现webapi控制器

api层添加volo.abp.identity.httpapi引用:

dotnet add lemon.usercenter.httpapi/lemon.usercenter.httpapi.csproj package volo.abp.identity.httpapi

创建模块类:

using lemon.usercenter.application;
using volo.abp.identity;
using volo.abp.modularity;

namespace lemon.usercenter.httpapi
{
    [dependson(typeof(abpidentityhttpapimodule),
    typeof(usercenterapplicationmodule))]
    public class usercenterhttpapimodule : abpmodule
    {
        
    }
}

创建controller:

using system.threading.tasks;
using lemon.usercenter.application;
using lemon.usercenter.domain;
using microsoft.aspnetcore.mvc;
using volo.abp.aspnetcore.mvc;

namespace lemon.usercenter.httpapi.controllers
{
    [route("api/user")]
    public class usercontroller : abpcontroller
    {
        private readonly iuserservice _userservice;
        public usercontroller(iuserservice userservice)
        {
            this._userservice = userservice;
        }

        [httppost("create")]
        public async task<iactionresult> create(userdata data)
        {
            var result = await _userservice.create(data);
            return json(result);
        }
    }
}

7. 在api hosting实现项目启动项

添加volo.abp.autofac引用:

dotnet add lemon.usercenter.httpapi.hosting/lemon.usercenter.httpapi.hosting.csproj package volo.abp.autofac

创建模块类

using lemon.usercenter.domain;
using lemon.usercenter.entityframeworkcore;
using microsoft.aspnetcore.builder;
using microsoft.extensions.hosting;
using volo.abp;
using volo.abp.aspnetcore.mvc;
using volo.abp.autofac;
using volo.abp.modularity;

namespace lemon.usercenter.httpapi.hosting
{
    [dependson(typeof(usercenterhttpapimodule),
                typeof(usercenterdomainmodule),
                typeof(usercenterentityframeworkcoremodule),
                typeof(abpaspnetcoremvcmodule),
                typeof(abpautofacmodule))]
    public class usercenterhttpapihostingmodule: abpmodule
    {
        public override void onapplicationinitialization(
            applicationinitializationcontext context)
        {
            var app = context.getapplicationbuilder();
            var env = context.getenvironment();

            if (env.isdevelopment())
            {
                app.usedeveloperexceptionpage();
            }
            else
            {
                app.useexceptionhandler("/error");
            }

            app.usestaticfiles();
            app.userouting();
            app.usemvcwithdefaultrouteandarea();
        }
    }
}

修改program类,新增useautofac:

using microsoft.aspnetcore.hosting;
using microsoft.extensions.hosting;

namespace lemon.usercenter.httpapi.hosting
{
    public class program
    {
        public static void main(string[] args)
        {
            createhostbuilder(args).build().run();
        }

        public static ihostbuilder createhostbuilder(string[] args) =>
            host.createdefaultbuilder(args)
                .configurewebhostdefaults(webbuilder =>
                {
                    webbuilder.usestartup<startup>();
                }).useautofac();
    }
}

修改startup类:

using microsoft.aspnetcore.builder;
using microsoft.extensions.dependencyinjection;

namespace lemon.usercenter.httpapi.hosting
{
    public class startup
    {
        public void configureservices(iservicecollection services)
        {
            services.addapplication<usercenterhttpapihostingmodule>();
        }

        public void configure(iapplicationbuilder app)
        {
            app.initializeapplication();
        }
    }
}

8. 运行服务

cd lemon.usercenter.httpapi.hosting
dotnet watch run

9. 最后我们用postman来测试api接口服务是否可以正常使用。

操作如下图:

数据库结果如下:

总结

以上就是接口服务的构建过程,主要参考了abp cli生成的项目结构,但是又有所不同。整个分层架构还可以继续优化,这个就见仁见智吧。后续还会继续分享abp的相关知识,例如identity server 4、缓存、微服务等。

github: