三、自定义Abp Vnext框架代码生成模板

我们知道通过abp cli命令可以快速的搭建一个最基本的abp项目环境,但我们项目中一般都需要使用自己的UI、数据库和基础配置,如果每次都用官方默认模板创建项目,那就需要每次都重复前两章的过程来搭建基础代码框架,这显然太浪费时间了;

这章我们将介绍如何打造自己的abp框架代码模板。

首先,到github上下载abp源码,https://github.com/abpframework/abp/releases,文中使用的v5.0.0-rc.1版本;解压后复制templates目录到磁盘任意位置

这里我们只修改app项目的模板,打开app/aspnet-core目录下的MyCompanyName.MyProjectName.sln解决方案文件,之前我们项目都是angular前端,mysql数据库,apiHost集成IdentityServer的,只需要要修改以下的项目即可:

为了将模板从abp源码中独立出来发布,首先将项目文件中所有的abp项目引用替换为包引用,比如MyCompanyName.Application项目:

然后按照第一章的方法修改MyCompanyName.MyProjectName.EntityFrameworkCore项目,使其支持MySql数据库;

另外在此基础上,我们可以添加点别的基础功能,或者删除点没用的东西

1、删除掉多余的多语言资源

定位到MyCompanyName.MyProjectName.Domain.Shared项目的Localization/MyProjectName目录,删除多余的多语言资源,只保留自己常用,这里我们只保留中文和英文

继续定位到MyCompanyName.MyProjectName.HttpApi.HostWithIds项目的MyProjectNameHttpApiHostModule文件,移除多余的语言定义

2、配置审计日志参数

打开MyCompanyName.MyProjectName.HttpApi.HostWithIds项目的MyProjectNameHttpApiHostModule文件,在ConfigureServices方法中添加如下内容

        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            var configuration = context.Services.GetConfiguration();
            var hostingEnvironment = context.Services.GetHostingEnvironment();

            Configure<AbpAuditingOptions>(options =>
            {
                options.IsEnabled = true;
                options.IsEnabledForAnonymousUsers = false; // 不记录匿名用户的日志
                options.IsEnabledForGetRequests = false; // 不记录Get请求用户的日志
            });
            
            ...
            ...
          }

 此处根据自身情况设置吧,按默认选项在实际生产环境中可能会产生大量日志,我在之前项目中1个月产生10多万条,按上面配置就好多了

 3、添加文件上传下载支持

为配合后面章节的内容,将文件处理相关的配置做到模板里,后面生成代码就直接支持文件处理了

还是在打开MyCompanyName.MyProjectName.HttpApi.HostWithIds项目的MyProjectNameHttpApiHostModule文件中,修改ConfigureConventionalControllers方法如下

        private void ConfigureConventionalControllers()
        {
            Configure<AbpAspNetCoreMvcOptions>(options =>
            {
                options.ConventionalControllers.Create(typeof(MyProjectNameApplicationModule).Assembly);
                options.ConventionalControllers.FormBodyBindingIgnoredTypes.Add(typeof(RemoteStreamContent));
            });
        }

修改ConfigureSwaggerServices方法的代码如下

                options =>
                {
                    options.SwaggerDoc("v1", new OpenApiInfo {Title = "FixtrueControl API", Version = "v1"});
                    options.DocInclusionPredicate((docName, description) => true);
                    options.CustomSchemaIds(type => type.FullName);
                    options.MapType<FileContentResult>(() => new OpenApiSchema { Type = "string", Format = "binary" });
                });

 修改ConfigureCors方法中添的代码如下:

                options.AddPolicy(DefaultCorsPolicyName, builder =>
                {
                    builder
                        .WithOrigins(
                            configuration["App:CorsOrigins"]
                                .Split(",", StringSplitOptions.RemoveEmptyEntries)
                                .Select(o => o.RemovePostFix("/"))
                                .ToArray()
                        )
                        .WithAbpExposedHeaders()
                        .WithExposedHeaders("Content-Disposition") // file-download
                        .SetIsOriginAllowedToAllowWildcardSubdomains()
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowCredentials();
                });

4、修改Serilog日志记录参数

打开MyCompanyName.MyProjectName.HttpApi.HostWithIds项目的Program.cs文件,将如下内容修改如下:

                // 始终打印控制台日志
                .WriteTo.Async(c => c.Console())
#if RELEASE
                // 尽在发布版本中包含文件日志
                .WriteTo.Async(c => c.File("logs/logs.txt", rollingInterval: RollingInterval.Day))
#endif
                .Crea

这么修改是因为按照原来方式,我将程序部署到docker中时,无法查看控制台日志,另外我在debug模式时只要看控制台日志就行了,不要写文件日志

5、继承的多语言资源问题

打开MyCompanyName.MyProjectName.HttpApi的MyProjectNameHttpApiModule文件,定位到AddBaseTypes处,此处应该是可以不要的,因为在angular中可以通过资源前缀定位到任意其他模块的多语言资源的,添加AddBaseTypes会在appConfiguration配置中附带BaseType中所有的资源项,我们通过api/abp/application-configuration接口访问查看结果就可以发现每个abp自带的业务模块都包含同样的AbpUiResource多语言资源项目,如果我们自己的所有模块再都加上这些资源,这个接口返回的json内容就会增大不少;个人建议最多只在主项目中继承AbpUiResource,这样前端可以不用附带资源前缀就可以访问多语言资源;在自建的模块中全部不要继承AbpUiResource

6、前端api访问代理类生成配置

这个配置在自定义模块是要用到的,因为我们通常不会将所有功能都在一个模块中完成,分模块后前端代理类的生成也需要分模块,这个在后面章节会详细介绍

在MyCompanyName.MyProjectName.Application.Contracts项目中添加MyProjectNameRemoteServiceConsts.cs类,填充文件内容如下:

namespace MyCompanyName.MyProjectName
{
    public class MyProjectNameRemoteServiceConsts
    {
        public const string RemoteServiceName = "MyProjectName";

        public const string AreaName = "my-project-name";
    }
}

7、在数据库迁移时添加默认的角色

在MyCompanyName.MyProjectName.Domain项目中添加目录Identity,在改目录下添加DefaultRolesDataSeedContributor.cs文件,文件内容如下:

using Microsoft.AspNetCore.Identity;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.Identity;
using Volo.Abp.MultiTenancy;

namespace MyCompanyName.MyProjectName.Identity
{
    public class DefaultRolesDataSeedContributor : IDataSeedContributor, ITransientDependency
    {
        protected IGuidGenerator GuidGenerator { get; }
        protected IdentityRoleManager RoleManager { get; }
        protected ICurrentTenant CurrentTenant { get; }
        protected ILookupNormalizer LookupNormalizer { get; }
        protected IIdentityRoleRepository RoleRepository { get; }
        public DefaultRolesDataSeedContributor(IGuidGenerator guidGenerator, ILookupNormalizer lookupNormalizer,
            IdentityRoleManager roleManager, ICurrentTenant currentTenant, IIdentityRoleRepository roleRepository)
        {
            LookupNormalizer = lookupNormalizer;
            GuidGenerator = guidGenerator;
            CurrentTenant = currentTenant;
            RoleManager = roleManager;
            RoleRepository = roleRepository;
        }
        public async Task SeedAsync(DataSeedContext context)
        {
            var tenantId = context?.TenantId;
            using (CurrentTenant.Change(tenantId))
            {

                // 添加一个ordinary角色
                const string ordinaryRoleName = "ordinary";
                var ordinaryRole =
                    await RoleRepository.FindByNormalizedNameAsync(LookupNormalizer.NormalizeName(ordinaryRoleName));
                if (ordinaryRole == null)
                {
                    ordinaryRole = new Volo.Abp.Identity.IdentityRole(
                          GuidGenerator.Create(),
                          ordinaryRoleName,
                          tenantId
                      )
                    {
                        IsStatic = true,
                        IsPublic = true, 
                        IsDefault = true // 将角色设置为默认角色,创建用户时会自动赋予该角色
                    };

                    (await RoleManager.CreateAsync(ordinaryRole)).CheckErrors();
                }
            }
        }
    }

}

abp在数据迁移时会检测到所有IDataSeedContributor,因此会执行DefaultRolesDataSeedContributor 中的SeedAsync方法,插入默认角色,这样在用户自行注册或者管理员添加用户时就默认拥有ordinary的权限了

8、angular前端修改

这里按照上一节coreui的方案进行修改,就不赘述了

9、使用模板生成项目

进入到F:\BlogSamples\templates\app目录(个人模板存放位置),选中angular和aspnet-core目录,将这两个目录打包到app-5.0.0-rc.1.zip中

在任意目录打开控制台程序,执行abp cli 命令如下:

abp new MyGroup.TestProject  -u angular --mobile none -d ef -csf -cs "server=192.168.100.175;port=3306;database=abp_test2;uid=test;pwd=Test123$;SslMode=none" -ts "F:\BlogSamples\templates\app" -v 5.0.0-rc.1

代码生成成功后,用vs2022打开aspnet-core解决方案,先运行MyGroup.TestProject.DbMigrator项目执行数据迁移,然后编译运行Api.Host项目,用vscode打开angular目录,执行npm install 和npm start ,浏览器打开http://localhost:4200/后,熟悉的界面又回来了,同时我们也发现默认角色已经加进来了

 也可以将app-5.0.0-rc.1.zip文件上传到个人网站中,在命令中只需将本地磁盘地址替换为网络地址即可

本章源码

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沝林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值