EF Core 6中如何在IEntityTypeConfiguration中使用自定义接口
EF Core 内置的无参重载 ApplyConfigurationsFromAssembly(Assembly) 批量加载配置时,内部通过反射调用配置类的无参构造函数创建实例,完全不会接入依赖注入容器做服务解析。
你给FooConfiguration定义了带IFooDomainService参数的构造函数后,类中不存在无参构造,反射实例化直接失败,对应配置类不会被加载,执行迁移时Configure方法自然不会触发。
- 替换批量加载配置的方法重载
使用带实例化工厂参数的ApplyConfigurationsFromAssembly重载,自定义配置类的实例化逻辑,接入DI容器自动解析依赖:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 获取当前DbContext关联的服务提供者 var serviceProvider = this.GetService<IServiceProvider>(); modelBuilder.ApplyConfigurationsFromAssembly( assembly: typeof(AppDbContext).Assembly, instanceFactory: type => ActivatorUtilities.CreateInstance(serviceProvider, type) ); }
提示:如果代码中找不到
GetService扩展方法,需要引入命名空间Microsoft.EntityFrameworkCore.Infrastructure。
ActivatorUtilities.CreateInstance会自动识别配置类构造函数的所有参数,从服务容器中解析对应实例完成注入,不需要手动给每个配置类传参。
提前注册依赖服务
确保你要注入的IFooDomainService已经正确注册到DbContext使用的服务容器中:- 运行时场景:在应用启动的服务注册阶段(比如ASP.NET Core的
Program.cs里)完成服务注册即可 - 设计时迁移场景(执行
add-migration命令时):如果服务不涉及特殊逻辑,默认的设计时服务容器可以直接解析;如果需要自定义注册,需要实现IDesignTimeServices接口配置设计时服务。
- 运行时场景:在应用启动的服务注册阶段(比如ASP.NET Core的
注意使用场景限制
不建议在IEntityTypeConfiguration的Configure方法中注入带运行时逻辑的服务生成HasData种子数据:Configure方法是在模型构建、编译阶段执行的,执行时机是生成迁移、模型首次加载的时候,不是每次应用启动都执行。如果后续修改了IFooDomainService里生成种子数据的逻辑,已经生成的迁移快照不会自动更新,很容易出现模型和实际数据库结构/种子数据不匹配的问题。
如果要做动态种子数据初始化,推荐单独实现种子服务,在应用启动、DbContext初始化完成后单独执行种子逻辑,不要耦合到实体配置阶段。
内容的提问来源于stack exchange,提问作者Okan Karadag

