微软教程http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application建议实现dispose模式,如下所示:
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
为什么我应该这样做,为什么我不能简单地处理上下文和足够的,如果我只使用会发生什么:
context.Dispose()
实施微软部署模式的目标是什么?
答案 0 :(得分:5)
你可以使用......
public void Dispose() // IDisposable implementation
{
context.Dispose();
}
...没有虚拟Dispose
重载且没有私有disposed
标志,因为
Dispose
,以便第二次调用时不会发生任何事情,并且不会抛出任何异常Dispose
,它将确保在垃圾收集上释放数据库连接最后一点并不意味着你根本不需要调用context.Dispose()
,因为垃圾收集器最终确定上下文的时间点是不确定的,它可能晚于时间点。您已经创建了一个新的上下文实例,并可能将它与相同的实体一起使用 - 这可能会导致一些麻烦。所以:始终明确地或通过using
块来处理上下文。
我也怀疑GC.SuppressFinalize(this);
在这里有任何影响,因为你的类中没有终结器,也没有基类,所以没有什么可以抑制的。
在我看来,您的示例中的模式是一个片段(错过了终结器/析构函数实现),如果您必须在类中处理自己的非托管资源,这可能很有用。但对于您的UnitOfWork类,您不必这样做。非托管资源(数据库连接)由上下文管理,您只需通过调用context.Dispose()
将工作委托给它。
答案 1 :(得分:2)
客户端代码应仅与存储库通信。存储库隐藏了调用代码的实现细节(例如使用DBContext,EF和您正在使用的任何后端),这是存储库模式的主要目标之一。
这就是为什么存储库的调用代码不能调用context.dispose的原因。它甚至不应该知道背景。它只知道存储库并调用其Dispose方法(显式或最好使用使用关键字)