[英]Is it bad practice to have a repository that manually opens and closes a db connection?
環境:ASP.NET MVC3 C#
說我有一些存儲庫(半偽):
public interface IRepository
{
create();read();update();delete();opendb();closedb();
}
public class CarRepository : IRepository
{
private DbContext namedDbContext;
public void opendb()
{
namedDbContext = new DbContext();
}
public void closedb()
{
namedDbContext.dispose();
}
}
然后在控制器中注入存儲庫,並按以下方式使用它來手動控制數據庫連接的生存期:
public class SomeController : Controller
{
private IRepository CarRepository;
public void SomeController(IRepository _carRepository)
{
CarRepository = _carRepository;
}
public ActionResult SomeAction(int CarId)
{
CarRepository.opendb();
var car = CarRepository.read(CarId);
CarRepository.closedb();
}
}
這是否被認為是不好的做法,因為它正在從存儲庫中控制連接並將其放置在控制器中? 我擔心使用依賴項注入會導致內存泄漏,並希望確保不會打開重復的連接,也不會長時間運行和未使用它們。
是。 當然。 大多數ADO.NET驅動程序使用連接池,因此實際的連接過程並不那么繁重。 而且您擁有TransactionScope
,它可以處理多個連接上的事務,但是它不會像通過一個連接上的一個事務一樣快。
我擔心使用依賴項注入會導致內存泄漏,並希望確保不會打開重復的連接,也不會長時間運行和未使用它們。
IoC將保證清理連接(龐大的用戶群已確保做到這一點)。 不能保證程序員會在所有地方進行清理。
存儲庫的一部分是抽象化持久性細節。
我看到您的建議有兩個問題:
opendb()
方法返回IDisposable
(連接對象),並將操作包裝在using
塊中,以確保關閉連接。 通常,您可以讓存儲庫為每個方法創建一個連接,因此只需在存儲庫方法中正確進行連接即可。 當您想對存儲庫執行多項操作而又不為每個組件使用單獨的連接時,挑戰就來了。
為此,您可以從存儲庫中公開工作單元的概念。 您的工作單元將實現存儲庫方法的接口,因此您不能在工作單元之外調用它們。 它還將實現IDisposable
,因此,每當調用存儲庫時,都將使用using
塊。 在內部,存儲庫將管理連接,但既不會公開連接也不會“談論它”。
例如:
public ActionResult SomeAction(int CarId)
{
using (var repo = CarRepository.BeginUnitOfWork())
{
var car = repo.read(CarId);
// do something meaningful with the car, do more with the repo, etc.
}
}
Repository模式提供了持久層的抽象。 它不應公開任何持久性詳細信息,例如db connection。 如果存儲是xml文件或雲存儲怎么辦?
所以是的,這是不好的做法。 如果需要更多控制,則可以使存儲庫使用工作單元模式,以便更高級別的用戶可以決定何時提交事務,僅此而已。 存儲庫不應該公開任何數據庫知識。
作為內存泄漏的AS,使存儲庫實現IDIsposable(在其中關閉任何未完成的打開連接),並僅確保DI容器根據請求管理存儲庫實例,它將對它調用Dispose。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.