2

微软教程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()

微软的 dispose 模式的实现目标有哪些?

4

2 回答 2

5

你可以只用...

    public void Dispose() // IDisposable implementation
    {
        context.Dispose();
    }

...没有虚拟Dispose重载,也没有私有disposed标志,因为

  • 上下文本身检查是否Dispose已被调用,以便在第二次调用时不会发生任何事情并且不会引发异常
  • Dispose上下文类有自己的终结器,如果您没有显式调用,它将确保数据库连接在垃圾收集时释放

最后一点并不意味着您根本不需要调用context.Dispose(),因为垃圾收集器最终确定上下文的时间点是不确定的,它可能晚于您创建新上下文实例的时间点和可能与相同的实体一起使用它 - 这可能会导致一些麻烦。所以:总是显式地或通过using块来处理上下文。

我也怀疑这GC.SuppressFinalize(this);有什么影响,因为你的类和基类中都没有终结器,所以没有什么可以抑制的。

在我看来,您示例中的模式是一个片段(错过了终结器/析构函数的实现),如果您必须在类中处理自己的非托管资源,这可能很有用。但是对于您的 UnitOfWork 课程,您不必这样做。非托管资源(数据库连接)由上下文管理,您只需通过调用context.Dispose().

于 2012-10-08T19:39:19.690 回答
2

客户端代码应该只与存储库对话。存储库从调用代码中隐藏了实现细节(例如使用 DBContext、EF 和您正在使用的任何后端),这是存储库模式的主要目标之一。

这就是为什么对存储库的调用代码不能也不应该调用 context.dispose。它甚至不应该知道上下文。它只知道存储库并调用其 Dispose 方法(显式或最好使用using关键字)

于 2012-10-07T21:02:39.713 回答