[英]EF6 DbContext IOC Dependency
我在Windows服務/控制台應用程序中使用EF6。 我已經為我的業務層接口和實現成功實現了IOC / DI。 使用構造函數注入。 我也在使用對象數據庫,任務並行庫。 為了更好的表現,我很高興。
還使用System.IO.Abstractions使我的代碼更易於測試。
EF6使用.tt文件為所有域實體創建POCO clases,非常方便。 為了執行數據庫查詢,我寫的每一個地方
using(var db = new MyContext())
{
// code reading from/writing to database
...
...
}
我知道這不是正確的做法,並在我的代碼中的各個地方發出噪音。 我想讓它松散耦合。 現在我的數據庫操作 - 我很困惑如何前進,使它更可測試和松散耦合..任何人都可以指出一個很好的例子,可以參考的文章。
我想要實現的兩個主要方面是對連接字符串配置(對於各種服務器部署)有更多的控制, DbContext
在我的代碼中非常松散地耦合。
要解決分離(和測試)問題,您可以為DbContext
( IMyDbContext
)創建自己的接口,並重新公開所有類型化的實體DbSets
, SaveChanges()
以及可能的其他一些方法。 您還應該使此接口為Disposable
。
public interface IMyDbContext : IDisposable
{
IDbSet<Foo> Foos { get; set; }
IDbSet<Bar> Bars { get; set; }
int SaveChanges();
DbEntityEntry<T> Entry<T>(T entity) where T : class;
}
(您也可以考慮接口的只讀和讀寫版本)
然后更改具體的DbContext
以實現此接口。 您現在可以合理地與DbContext
(用於單元測試等)分離,但仍然可以訪問IQueryable
的有用性,固有工作單元和DbContext
提供的緩存。
然后,這里有兩個選項,用於將IMyDbContext
注入到您的業務/服務類中
IDbContext
要么
DbContext
,然后對IMyDbContextFactory
工廠接口進行構造函數注入(您將需要接口,而不是具體工廠,再次用於模擬測試目的)。 這里的選擇取決於您需要對DbContext
執行的DbContext
。 在IoC容器中配置#1可能很棘手,因為您需要將生命周期管理移交給容器。 但是,如果可以為每個請求配置新實例,那么這在Web應用程序中可能是有益的,因此如果請求(假設單個線程)可以將其用作緩存。
我個人更喜歡#2,因為這允許直接管理上下文:
using(var db = _myContextFactory.CreateDB())
{
db.SaveChanges();
}
但顯然,我們失去了長期環境(如緩存)的任何潛在好處。 但是,如果需要,還有許多其他替代技術可用於緩存。
需要注意的是: DbContext
根本不是線程安全的 - 如果你使用的是TPL,請確保每個任務都獲得自己的DbContext
實例 - 例如,使用Parallel.For
/ ForEach
的localinit
重載來使用它時實例化它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.