1. 安装ABP CLI
ABP以dotnet CLI工具的形式提供, 使用一下命令安装:
dotnet tool install -g Volo.Abp.Cli
其中, 使用-g参数指定全局安装. 如果需要了解更多关于dotnet CLI工具的内容, 请参考Microsoft Docs 相关的章节.
2. 使用ABP CLI创建ABP项目
使用以下命令来创建项目:
abp new YourProjectName [options]
如:
abp new Acme.BookStore
abp new Acme.BookStore --tiered
abp new Acme.BookStore -u angular
abp new Acme.BookStore -u angular -d mongodb
abp new Acme.BookStore -m none
abp new Acme.BookStore -m react-native
abp new Acme.BookStore -d mongodb
abp new Acme.BookStore -d mongodb -o d:\my-project
abp new Acme.BookStore -t module
abp new Acme.BookStore -t module --no-ui
abp new Acme.BookStore -t console
abp new Acme.BookStore -ts "D:\localTemplate\abp"
abp new Acme.BookStore -csf false
abp new Acme.BookStore --local-framework-ref --abp-path "D:\github\abp"
abp new Acme.BookStore --connection-string
"Server=myServerName\myInstanceName;Database=myDatabase;User
Id=myUsername;Password=myPassword"
需要了解全部信息, 请参考ABP CLI 相关页面.
3. 创建一个Web项目
我们目标是创建一个使用Razor Pages作为UI层, 使用EF Core作为ORM, 以及MySQL作为数据源的Web项目.
首先创建项目:
abp new KNet.Manage -o KNet.Manage
使用以上命令, 我们创建了一个名为KNet.Manage的项目, 项目将创建到使用-o参数指定的目录中.
这里使用Visual Studio打开解决方案, 项目如图:
以下简述了各项目的作用:
项目名
作用
*.Application
应用服务层, 包含应用服务实现
*.Application.Contracts
应用程序层, 包含DTO和应用服务接口
*.DbMigrator
一个控制台使用程序,可以在开发和生产环境迁移数据库架构和初始化种子数据.
*.Domain
*.Domain.Shared
*.EntityFrameworkCore
*.EntityFrameworkCOre.DbMigrations
*.HttpApi
*.HttpApi.Client
*.Web
4. 修改默认的数据源为MySQL
删除Volo.Abp.EntityFrameworkCore.SqlServer NuGet包, 安装Volo.Abp.EntityFrameworkCore.MySQL包(在KNet.Manage.EntityFrameworkCore项目);
ManageEntityFrameworkCoreModule类:
添加引用: using Volo.Abp.EntityFrameworkCore.MySQL, 同时删除引用: using Volo.Abp.EntityFrameworkCore.SqlServer;
使用typeof(AbpEntityFrameworkCoreMySQLModule)替换ManageEntityFrameworkCoreModule类的DependsOn特性参数typeof(AbpEntityFrameworkCoreSqlServerModule);
在ConfigureServices方法中, 使用options.UseMySQL()替换options.UseSqlServer().
ManageMigrationsDbContextFactory类: 在CreateDbContext方法中, 使用UseMySql替换UseSqlServer;
修改appsettings.json数据库连接字符串(在项目KNet.Manage.DbMigrator和项目KNet.Manage.Web中);
重新生成迁移:
删除KNet.Manage.EntityFrameworkCore.DbMigrations项目下的Migrations文件夹, 并重新生成解决方案;
在包管理控制台中运行 Add-Migration "Initial"(在解决方案资源管理器选择 .DbMigrator (或 .Web) 做为启动项目并且选择 .EntityFrameworkCore.DbMigrations 做为默认项目).
5. 实体和数据迁移
首先创建一个实体. 以一个简单的Application对象为例:
在KNet.Manage.Domain项目中创建Applications文件夹, 并在文件夹内创建Application对象:
public class Application : Entity
{
public string AppId { get; set; }
public string AppKey { get; set; }
public string AppName { get; set; }
public bool Enabled { get; set; }
public DateTime CreateTime { get; set; }
public PlatformType AppPlatform { get; set; }
}
其中, 枚举PlatformType定义在项目KNet.Manage.Domain.Shared的Applications文件夹中:
public enum PlatformType
{
Web = 0,
Mobile = 1,
Android = 2,
iOS = 3,
Client = 4,
Pc = 5,
Mac = 6,
Linux = 7,
MiniProgram = 8
}
将Application实体添加到KNet.Manage.EntityFrameworkCore项目的ManageDbContext中:
public DbSet Applications { get; set; }
在KNet.Manage.EntityFramewordCore项目中的ManageDbContextModelCreatingExtensions类中, 添加Application对象的映射配置:
public static void ConfigureManage(this ModelBuilder builder)
{
Check.NotNull(builder, nameof(builder));
builder.Entity(a =>
{
a.ToTable(ManageConsts.DbTablePrefix + "application",
ManageConsts.DbSchema);
a.ConfigureByConvention();
a.Property(x => x.AppId).IsRequired().HasMaxLength(36);
});
}
运行迁移:
Add-Migration "Created_Application_Entity"
添加种子数据(可选)
在KNet.Manage.Domain项目中添加以下类:
public class ApplicationDataSeederContributor : IDataSeedContributor, ITransientDependency
{
private readonly IRepository _applicationRepository;
public ApplicationDataSeederContributor(IRepository applicationRepository)
{
_applicationRepository = applicationRepository;
}
public async Task SeedAsync(DataSeedContext context)
{
if (await _applicationRepository.GetCountAsync() <= 0)
{
await _applicationRepository.InsertAsync(
new Application
{
AppId = "system"
},
autoSave: true
);
}
}
}
然后运行KNet.Manage.DbMigrator项目来完成更新数据库过程.
执行完毕后, 可以看到数据库中新增了Abp内置的数据表, 以及Application表(knet_aams_application).
6. 创建应用程序
定义DTO.
创建ApplicationDto. 在KNet.Manage.Application.Contracts项目创建Applications文件夹, 然后在文件夹中创建ApplicationDTO类:
public class ApplicationDto : EntityDto
{
public string AppId { get; set; }
public string AppKey { get; set; }
public string AppName { get; set; }
public bool Enabled { get; set; }
public DateTime CreateTime { get; set; }
public PlatformType AppPlatform { get; set; }
}
因为DTO类被用来把数据从应用层传递到表示层, 所以需要有从Application到ApplicationDto类的转换. ABP Framework使用AutoMapper库来完成此操作, 所以需要在KNet.Manage.Application项目的ManageApplicationAutoMapperProfile类中定义映射:
public ManageApplicationAutoMapperProfile()
{
CreateMap();
}
创建CreateUpdateApplicationDto. 在KNet.Manage.Application.Contracts项目的Applications文件夹中创建CreateUpdateApplicationDto类:
public class CreateUpdateApplicationDto
{
[Required]
[StringLength(36)]
public string AppId { get; set; }
[Required]
public string AppKey { get; set; }
[Required]
public string AppName { get; set; }
public bool Enabled { get; set; }
public DateTime CreateTime { get; set; }
[Required]
public PlatformType AppPlatform { get; set; }
}
CreateUpdateApplicationDto类中添加了一些属性的约束条件, 在创建或更新Application时, 表单中的数据如果不满足条件, 则会拒绝创建或更新操作.
同样地, 需要在KNet.Manage.Application项目的ManageApplicationAutoMapperProfile类中定义映射. 最终的映射如下:
public ManageApplicationAutoMapperProfile()
{
CreateMap();
CreateMap();
}
定义IApplicationAppService接口. 在KNet.Manage.Application.Contracts项目的Applications文件夹下, 创建IApplicationAppService接口:
public interface IApplicationAppService : ICrudAppService<
ApplicationDto,
int,
PagedAndSortedResultRequestDto,
CreateUpdateApplicationDto>
{
}
其中ICrudAppService定义了CRUD方法.
创建ApplicationAppService实现. 在KNet.Manage.Application项目中创建Applications文件夹, 并在文件夹内创建ApplicationAppService类:
public class ApplicationAppService : CrudAppService<
Application,
ApplicationDto,
int,
PagedAndSortedResultRequestDto,
CreateUpdateApplicationDto>,
IApplicationAppService
{
public ApplicationAppService(IRepository repository) : base(repository)
{
}
}
7. 自动生成WebApi
至此, ABP Framework已经自动生成了Application对象的HTTP API端点. 我们可以用AJAX使用他们.
运行KNet.Manage.Web项目, 并在浏览器访问https://localhost:*/swagger/, 可以看到REST风格的WebApi:
访问GET /api/app/application, 得到了种子数据:
{
"totalCount": 1,
"items": [
{
"appId": "system",
"appKey": null,
"appName": null,
"enabled": false,
"createTime": "0001-01-01T00:00:00",
"appPlatform": 0,
"id": 1
}
]
}
8. 参考资料