.NET Core依赖注入问题:迁移调用ISeederService提示未注册
问题原因
你在迁移类的Up方法里新建了一个独立的ServiceCollection,只注册了ApplicationDbContext,完全没把ISeederService添加到这个容器中——你在服务模块里的注册是给应用启动时的容器用的,和迁移里的这个容器是两个毫无关联的实例,所以会报“未注册”的错误。
解决方案
方案1:在迁移的服务集合中补全依赖注册
修改迁移类的Up方法,在构建服务容器时,同时注册ISeederService及其实现,并且要保证ApplicationDbContext的配置和应用中的一致(比如连接字符串):
public partial class seedingData: Migration { protected override void Up(MigrationBuilder migrationBuilder) { var services = new ServiceCollection(); // 这里要和应用中DbContext的注册配置保持一致 services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer("你的数据库连接字符串")); // 注册ISeederService services.AddScoped<ISeederService, SeederService>(); using (var serviceProvider = services.BuildServiceProvider()) { var seederService = serviceProvider.GetRequiredService<ISeederService>(); seederService.SeedMenuData(); } } protected override void Down(MigrationBuilder migrationBuilder) { // 如需回滚种子数据,在此实现逻辑 } }
方案2:将种子数据移到应用启动时执行(推荐)
迁移的核心职责是维护数据库结构,种子数据放在应用启动阶段处理更合理。你已经有启动时自动执行迁移的代码,直接在其后添加种子服务调用即可:
using (var scope = app.Services.CreateScope()) { var services = scope.ServiceProvider; var context = services.GetRequiredService<ApplicationDbContext>(); // 自动执行数据库迁移 context.Database.Migrate(); // 调用种子服务初始化数据 var seederService = services.GetRequiredService<ISeederService>(); seederService.SeedMenuData(); }
这种方式的优势:
- 复用应用已配置好的所有服务,无需重复注册依赖
- 迁移与种子数据职责分离,符合单一职责原则
- 避免迁移执行时可能出现的依赖缺失问题
内容的提问来源于stack exchange,提问作者Kamran Khan
相关产品推荐
相关产品推荐

