这里是你如何能实现DbContextFactory
或DbContextProxy<T>
这将创建正确的供应商和返回的例子它。
public interface IDbContextFactory
{
ApplicationContext Create();
}
public class DbContextFactory() : IDbContextFactory, IDisposable
{
private ApplicationContext context;
private bool disposing;
public DbContextFactory()
{
}
public ApplicationContext Create()
{
if(this.context==null)
{
// Get this value from some configuration
string providerType = ...;
// and the connection string for the database
string connectionString = ...;
var dbContextBuilder = new DbContextOptionsBuilder();
if(providerType == "MSSQL")
{
dbContextBuilder.UseSqlServer(connectionString);
}
else if(providerType == "Sqlite")
{
dbContextBuilder.UseSqlite(connectionString);
}
else
{
throw new InvalidOperationException("Invalid providerType");
}
this.context = new ApplicationContext(dbContextBuilder);
}
return this.context;
}
public void Dispose(){
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing){
if (disposing){
disposing?.Dispose();
}
}
}
另外,还要确保你实施一次性模式如上图所示,这样的背景下被尽快工厂被布置布置,防止的DbContext在内存中,一旦剩余时间超过必要的和免费的非托管资源尽可能。
最后注册的工厂为范围的,因为你将上下文本身:
services.AddScopedd<IDbContextFactory, DbContextFactory>();
更先进和通用的/可扩展的方法是通过创建一个IDbContextProxy<T>
类使用位反射,以获得正确的构造和DbContextOptionsBuilder
。
还可以创建IDbContextBuilder
,它抽象提供者的创建。
public class SqlServerDbContextBuilder IDbContextBuilder
{
public bool CanHandle(string providerType) => providerType == "SqlServer";
public T CreateDbContext<T>(connectionString)
{
T context = ... // Create the context here
return context;
}
}
然后你就可以选择正确的供应商W /只是做
// Inject "IEnumerable<IDbContextBuilder> builders" via constructor
var providerType = "SqlServer";
var builder = builders.Where(builder => builder.CanHandle(providerType)).First();
var context = builder.CreateDbContext<ApplicationContext>(connectionString);
,并增加新的类型提供的OA硬编码if/else
或switch
块是那么容易,因为添加的依赖和XxxDbContextBuilder
类。
请参阅here,here或here以获取有关此方法和类似方法的更多信息。
什么是用例?从我的观点来看,这似乎毫无意义。对于一个CMS或博客,你永远不会“只”改变数据库类型,而不需要关闭/重新启动应用程序 – Tseng
是的 - 但“第一次安装”时,你可以选择数据库提供商。 我希望允许客户端决定使用哪个提供程序 - 无需修改源代码。 – pwas
好吧,虽然技术上可以从应用程序中编辑project.json,然后重新启动应用程序,但我认为从安全角度来看这不是一个明智之举。在wordpress中,安装脚本随后被删除,这在编译系统中更难以解决,并且在那里出现安全问题。当然,没有人强迫你在启动时使用'AddDbContext',并通过一个抽象工厂解决你的数据库上下文,该工厂读取一个配置值并选择正确的提供者并手动构建它,但是你需要自己管理它的一生即处置它) – Tseng