[英]How to configure EF Core connection context to decouple packages dependencies?
我制作了一個使用Entity Framework Core處理持久性的庫。 面向SQL Server數據庫的Web API使用它。 此外,我針對SQLite數據庫進行了測試(單元測試)。
我使用配置文件以一種直接的方式完成了該任務。 因此,在擴展DBContext的類中,我使用以下內容實現了OnConfiguring:
if(isSqlServer) //don't mind where it comes from, it works fine
optionsBuilder.UseSqlServer(connectionString);
else
optionsBuilder.UseSqlite(connectionString);
似乎工作正常,但效果不理想。 假設我有這個項目:
由於UseSqlite方法是Microsoft.EntityFrameworkCore.Sqlite包的類中的靜態擴展方法,並且類似地,UseSqlServer方法是Microsoft.EntityFrameworkCore.SqlServer包的類中的靜態擴展方法,有兩件事使我感到困擾。
首先,我必須在三個項目中包括兩個依賴項,以避免在運行時出現錯誤“ System.IO.FileNotFoundException:無法加載文件或程序集Microsoft.EntityFrameworkCore.SqlServer(...)”。
其次,如果需要支持新的DBMS(Oracle,MySQL),則必須在這三個項目中包括新的依賴項。
我希望建立一個方案,其中項目PersistentLayer將不具有那些依賴關系,而PersistentLayerTests將僅依賴於Microsoft.EntityFrameworkCore.Sqlite,而WebAPI將僅依賴於Microsoft.EntityFrameworkCore.SqlServer。
還有另一種方法來配置連接上下文以解耦這些程序包依賴性嗎?
筆記:
你只需要讓你的DbContext的用戶(PersistenceLayerTests和的WebAPI項目)負責配置,而不是它的的DbContext本身。
DbContext 提供了一個接受DbContextOptions 的構造 函數 。 您需要公開此構造函數:
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options) { }
// ...
}
然后,您可以執行以下操作:
var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
if (isSqlServer) //don't mind where it comes from, it works fine
optionsBuilder.UseSqlServer(connectionString);
else
optionsBuilder.UseSqlite(connectionString);
using (var context = new MyDbContext(optionsBuilder.Options))
{
// ...
}
這似乎有些矯kill過正,但是在這種情況下,基本策略是放置一個公共界面,並將其分隔在不同的項目中。 不知道這是否是這種情況的最佳解決方案。
然后,不同的項目是獨立的(除了通用界面之外),並且很容易隨時間擴展。
關鍵部分是,在您的主項目中,僅引用接口組件,而不引用其中之一。 如果要避免FileNotFoundException
則必須在運行時加載混凝土(裝配體):此外:您需要一種機制來選擇合適的模型(通常稱為factory
。
讓我們考慮一下其中有3種(sql,sqllite和oracle)的情況:
首先要做的是創建一個公共接口以與適當的Db enginge通信,例如:
//separate assembly
public interface IDbEningeSelector
{
//added the option builder for simplicity: one could do better.
void Configure(string connectionString,IOptionsBuilder optionsBuilder);
}
接下來,僅針對具體實現創建3個單獨的項目,一個sql-lite,一個sql和一個oracle。
下一步:在三個項目中創建一個實現此目的的類:
//3 of these.
public class SqlEnging : IDbEngineSelector
{
public void Configure(string connectionString,IOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(connectionString);
}
}
好的,現在您可以選擇其中之一。
//the "thing"
IDbEngineSelector selector = null;
selector = //resolve through factory, possibly based on a flag.
selector.Configure(connectionString, optionsBuilder);
基本上,您已經完成了可擴展的,動態引用的數據庫提供程序系統。
對於動態程序集解析器,您需要按照本文中的描述進行加載: https : //www.codeproject.com/Articles/1194332/Resolving-Assemblies-in-NET-Core
這實際上將在運行時加載依賴項,為此目的,我建議保留一個特殊路徑以放置這些程序集。
我省略了工廠實現的詳細信息,我需要首先檢查在.net Core中執行此操作的正確方法,繼續...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.