我正在使用领域驱动设计,需要动态构建
DbContext
,因为我的模型构建器的程序集可以位于不同的位置,具体取决于当时访问它们的微服务。
我正在使用这样简单的东西
services.AddDbContext<PlDbContext>(options =>
{
options.UseNpgsql(connectionString);
});
然后我有这样的东西
public class PlDbContext : DbContext, IDbContext
{
public PlDbContext(DbContextOptions<PlDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}
}
我想要的是能够通过集会。
基本上,许多模型/地图都位于位于其他位置的类库中,并由一些服务共享。所以我只想说“从那里获取所有程序集”并在启动时应用它们。
我知道你可以这样做
typeOf(Yada).Assembly
在那里,但如果可能的话,我需要能够在启动时传递程序集,因为每个服务可能需要一个特定的子集。
我不是100%确定,因为我没有检查代码,但是这样的构建不会起作用吗?
public class PlDbContext : DbContext, IDbContext
{
private readonly Assembly _configurationAssembly;
public PlDbContext(DbContextOptions<PlDbContext> options, Assembly configurationAssembly)
: base(options)
{
_configurationAssembly = configurationAssembly;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfigurationsFromAssembly(_configurationAssembly);
}
}
对于 DI,您执行以下操作:
var configurationAssembly = typeof(SomeTypeFromYourDesiredAssembly).Assembly;
services.AddDbContext<PlDbContext>((serviceProvider, options) =>
{
options.UseNpgsql(connectionString);
}, ServiceLifetime.Scoped, ServiceLifetime.Scoped);
services.AddScoped<Assembly>(_ => configurationAssembly);
据我记得 EF 使用 DI,所以这个可能适合你。
如果 PlDbContext 的注册不起作用,您也可以考虑将其与以下内容结合起来:
services.AddTransient<PlDbContext>(provider =>
{
var options = provider.GetService<DbContextOptions<PlDbContext>>();
var configurationAssembly = typeof(SomeTypeFromYourDesiredAssembly).Assembly; //you may use some factory here or whatever
return new PlDbContext(options, configurationAssembly);
});
希望这能有所帮助。