手把手教你用Abp vnext构建API接口服务
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、缓存、微服务等。