我必须在所有类上实现IDisposable,还是基类足够?

时间:2011-11-15 15:57:05

标签: c# .net garbage-collection entity-framework-4.1 idisposable

我被告知我需要dispose of instances of my Entity Framework repository classes并且我创建了一个基类来强制执行此实现。

我需要咨询专家:通过基类实现IDisposable是否可以接受?

请注意,存储库类没有类成员变量。

/// Sample repository.  Note that I return List<T> as IEnumerable, 
/// and I use IDisposable 
///
public class CompanyRepository : DisposableBase, ICompanyRepository
{
    public IEnumerable<CompanyDetail> GetOneCompany(int? CompanyID)
    {
        var t = from c in _entities.CompanyDetail
                where c.CompanyID == CompanyID.Value
                select c;
        return t.ToList();
    }
}

/// <summary>
/// Disposable implementation based on advice from this link:
/// from Http://www.asp.net/entity-framework/tutorials/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
/// </summary>
public class DisposableBase : IDisposable
{
    protected TLSAdminEntities1 _entities;

    public DisposableBase()
    {
        _entities = new TLSAdminEntities1();
        disposed = false;
    }

    private bool disposed ;
    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                _entities.Dispose();
            }
        }
        this.disposed = true;
    }
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

5 个答案:

答案 0 :(得分:7)

答案是“它取决于”。

如果某个超类中的“Dispose()”方法已经足够,那么你肯定不需要在每个子类中重新实现它。

“超类”可能是基类;它可能是一个或多个子类。

这取决于您分配的内容以及需要清理的内容。

... IMHO

以下是MSDN所说的内容:

  

http://msdn.microsoft.com/en-us/magazine/cc163392.aspx

     

当您从一次性类型派生时,派生类型不派生   引入任何新资源,然后没有什么特别需要做的。   基本类型IDisposable实现将负责清理   它的资源和你的子类可以幸福地无知   细节。

&lt; =换句话说,您不必反复重复实施Dispose

......但......

  

但是,拥有一个包含new的子类也很常见   需要清理的资源。在这种情况下,您的课程需要   释放其资源,同时确保基类型   资源也被释放。通过覆盖清理方法来做到这一点,   释放资源,然后调用基类型进行清理   其资源,如图6所示。

答案 1 :(得分:4)

这取决于您是否在派生类中有资源需要处理。如果存在特定于派生类的资源,则仅在基类上实现IDisposable是不够的。

答案 2 :(得分:1)

通常说,你必须在每个类中实现IDispoable,你有自己实现IDisposable的私有成员。这些资源必须“释放”。我强烈建议您阅读CodeProject关于IDisposable模式的非常好的论文。

答案 3 :(得分:0)

没有。你也有子类。

如果你不习惯,GC仍然需要将其子项映射为未引用的 - 然后收集它们......所以你没有什么收入。

答案 4 :(得分:0)

使用基类进行处理是可以的。这里重要的是清理非托管资源,在这种情况下意味着关闭数据库连接。我认为你最好通过httpsodules或动作过滤器等​​方式连接到asp.net来处理你的工作单元并为每个请求的工作单元类型的设置进行处理,但是如果您只需要确保在存储库实例上调用dispose,具有处理实体框架上下文的基类就可以了(即使将它们与过滤器/模块一起使用,您仍然可以使用这些存储库的基类)。