這裏是你如何能實現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