我有一个Web应用程序,它应该被组成一系列插件到核心基础结构中。插件是一个已编译的CLR dll +一些内容文件,它们将放在某个位置。我正在使用Autofac来扫描和注册程序集中的类型,以及一些花哨的路由来从那里为控制器和资产提供服务。但是,由于每个插件程序集都可以包含一个DbContext(按照惯例,每个都将使用自己的数据库),我无法弄清楚该做什么。
现在我发现了很多关于如何使用多个上下文的内容,但这一切都需要知道这些在开发时的内容。我的应用程序不知道在运行时之前将使用哪些上下文。
理想情况下我想要的是某种方式
ApplyMigrations<MyDbContext, MyDbConfiguration>();
虽然我也不得不提供一组有序的迁移来应用(如果使用显式迁移)。
我目前磕磕绊绊的是标准
Database.SetInitializer(...)
因为它是一个静态单例,我系统中的每个dbcontext都有自己的初始化器。
答案 0 :(得分:1)
也许编写一个用于引导插件的接口,所以IPluginBootstrapper - 从这里你可以传入一个ContainerBuilder来添加到插件提供的服务集合,或者返回一个构建的Container,该插件构建并将其组合在主机上。通过这种方式,您可以将所有数据库种子/迁移工作的责任推送到每个插件中 - 所以当您使用新的dll时,当它被引导时,它可以运行它自己的升级路径。
另一种选择,也许你可以有一个定义一对类型的配置部分,所以Tuple告诉Autofac在plugins目录中找到所有这些对,然后用解决的东西调用SetInitializer?
答案 1 :(得分:1)
首先,所有SetInitializer
将IDatabaseInitializer
个对象存储在字典中,并将上下文Type作为键,因此理论上多次调用SetInitializer
应该可以正常工作。
另一方面,如果这不起作用,另一个选择是显式执行初始化:
class YourContext : DbContext
{
static YourContext()
{
Database.SetInitializer<YourContext>(YourMigratingDatabaseInitializer);
using (var context = new YourContext())
{
context.Database.Initialize(false);
}
}
public YourContext()
{
Database.SetInitializer<YourContext>(null);
}
}