0

环境: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();
    }
}

这是否被认为是不好的做法,因为它正在从存储库控制连接并将其放置在控制器中?我担心使用依赖注入会导致内存泄漏,并希望确保不会打开重复的连接,也不会长时间运行和未使用。

4

3 回答 3

2

是的。当然。大多数 ADO.NET 驱动程序使用连接池,因此实际的连接过程并没有那么繁重。你有TransactionScope它可以处理多个连接上的事务,但它不会像一个连接上的一个事务那么快。

我担心使用依赖注入会导致内存泄漏,并希望确保不会打开重复的连接,也不会长时间运行和未使用。

IoC 将保证清理连接(大量用户群已确保这一点)。不能保证程序员会在所有地方进行清理。

于 2012-02-13T19:31:36.430 回答
1

存储库的一部分正在抽象出持久性的细节。

我看到你的提议有两个问题:

  1. 通过将这些方法命名为“opendb”和“closedb”,您会过度泄漏抽象,并且
  2. 如果你沿着这条路线走,你应该IDisposable从方法中返回(连接对象)opendb(),并将操作包装在一个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.
     }
}
于 2012-02-13T19:44:31.420 回答
1

REpository 模式提供了持久层的抽象。它不应该暴露任何持久性细节,例如数据库连接。如果存储是 xml 文件或云存储怎么办?

所以,是的,这是不好的做法。如果您想要更多控制,您可以让存储库使用工作单元模式,以便更高级别应该决定何时提交事务,但仅此而已。存储库不应公开数据库的任何知识。

至于内存泄漏,使存储库实现 IDIsposable(关闭任何未完成的打开连接)并确保 DI 容器管理每个请求的存储库实例,它将调用 Dispose 。

于 2012-02-13T19:47:22.293 回答