在前面我们基本把应用框架的基础设施搭建完成。接下来我们就得着手处理一下种子数据的问题。
在一个基础框架里面,种子数据很重要,比如一些基础数据,初始用户等等,这些都需要初始化,否则程序启动却无法使用就很尴尬了。
IDataSeeder
首先定义一个种子数据接口
using Wheel.DependencyInjection; namespace Wheel.DataSeeders { public interface IDataSeeder : ITransientDependency { Task Seed(CancellationToken cancellationToken = default); } }
接下来所有的种子数据实现都需要继承这个接口。
DataSeederExtensions
封装一个扩展方法,获取所有IDataSeeder的实现,并执行数据初始化。
namespace Wheel.DataSeeders { public static class DataSeederExtensions { public static async Task<IApplicationBuilder> SeedData(this IApplicationBuilder app) { var dataSeeders = app.ApplicationServices.GetServices<IDataSeeder>(); foreach (var dataSeeder in dataSeeders) { await dataSeeder.Seed(); } return app; } } }
在Program中添加代码
var app = builder.Build(); //初始化种子信息 await app.SeedData();
这样就初步完成了种子数据的配置。
实现种子数据
用户角色种子数据
IdentityDataSeeder
using Microsoft.AspNetCore.Identity; using Wheel.Domain; using Wheel.Domain.Identity; namespace Wheel.DataSeeders.Identity { public class IdentityDataSeeder : IDataSeeder { private readonly IBasicRepository<Role, string> _roleRepository; private readonly IBasicRepository<User, string> _userRepository; private readonly UserManager<User> _userManager; private readonly IUserStore<User> _userStore; private readonly RoleManager<Role> _roleManager; public IdentityDataSeeder(IBasicRepository<Role, string> roleRepository, IBasicRepository<User, string> userRepository, UserManager<User> userManager, IUserStore<User> userStore, RoleManager<Role> roleManager) { _roleRepository = roleRepository; _userRepository = userRepository; _userManager = userManager; _userStore = userStore; _roleManager = roleManager; } public async Task Seed(CancellationToken cancellationToken = default) { if (!await _roleRepository.AnyAsync(a => a.Name == "admin")) { await _roleManager.CreateAsync(new Role("admin", Enums.RoleType.Admin)); } if (!await _roleRepository.AnyAsync(a => a.Name == "user")) { await _roleManager.CreateAsync(new Role("user", Enums.RoleType.App)); } if (!await _userRepository.AnyAsync(a => a.UserName == "admin")) { var adminUser = new User(); await _userStore.SetUserNameAsync(adminUser, "admin", cancellationToken); var emailStore = (IUserEmailStore<User>)_userStore; await emailStore.SetEmailAsync(adminUser, "136590076@qq.com", cancellationToken); await _userManager.CreateAsync(adminUser, "Wheel@2023"); await _userManager.AddToRoleAsync(adminUser, "admin"); await _userManager.UpdateAsync(adminUser); } } } }
这里初始化一个普通User角色和管理后台admin角色,以及一个admin角色的账号。
多语言种子数据
LocalizationDataSeeder
using Wheel.Domain; using Wheel.Domain.Localization; namespace Wheel.DataSeeders.Localization { public class LocalizationDataSeeder : IDataSeeder { private readonly IBasicRepository<LocalizationCulture, int> _localizationCultureRepository; public LocalizationDataSeeder(IBasicRepository<LocalizationCulture, int> localizationCultureRepository) { _localizationCultureRepository = localizationCultureRepository; } public async Task Seed(CancellationToken cancellationToken = default) { if (!(await _localizationCultureRepository.AnyAsync(cancellationToken))) { await _localizationCultureRepository.InsertAsync(new LocalizationCulture() { Name = "en" }, true); await _localizationCultureRepository.InsertAsync(new LocalizationCulture() { Name = "zh-CN"}, true); } } } }
菜单种子
MenuDataSeeder
using Wheel.Domain; using Wheel.Domain.Menus; namespace Wheel.DataSeeders.Identity { public class MenuDataSeeder : IDataSeeder { private readonly IBasicRepository<Menu, Guid> _menuRepository; public MenuDataSeeder(IBasicRepository<Menu, Guid> menuRepository) { _menuRepository = menuRepository; } public async Task Seed(CancellationToken cancellationToken = default) { if (!(await _menuRepository.AnyAsync(cancellationToken))) { await _menuRepository.InsertAsync(new Menu { Name = "SystemManage", DisplayName = "系统管理", Sort = 99, Id = Guid.NewGuid(), Icon = "SettingOutlined", Path = "/System", MenuType = Enums.MenuType.Menu, Children = new List<Menu> { new Menu { Name = "UserManage", DisplayName = "用户管理", Sort = 0, Id = Guid.NewGuid(), Path = "/System/User", MenuType = Enums.MenuType.Page }, new Menu { Name = "RoleManage", DisplayName = "角色管理", Sort = 1, Id = Guid.NewGuid(), Path = "/System/Role", MenuType = Enums.MenuType.Page, }, new Menu { Name = "PermissionManage", DisplayName = "权限管理", Sort = 2, Id = Guid.NewGuid(), Path = "/System/Permission", MenuType = Enums.MenuType.Page }, new Menu { Name = "MenuManage", DisplayName = "菜单管理", Sort = 3, Id = Guid.NewGuid(), Path = "/System/Menu", MenuType = Enums.MenuType.Page }, new Menu { Name = "LocalizationManage", DisplayName = "多语言管理", Sort = 4, Id = Guid.NewGuid(), Path = "/System/Localization", MenuType = Enums.MenuType.Page }, } }, true, cancellationToken: cancellationToken); } } } }
这里菜单初始化基础管理后台页面所需的菜单。
启动程序后,打开数据库



可以看到数据初始化成功。
这样就轻轻松松完成了我们种子数据的实现。
轮子仓库地址https://github.com/Wheel-Framework/Wheel
欢迎进群催更。
