简体   繁体   English

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

[英]Must I implement IDisposable on all classes, or is a base class sufficient?

I am told I need to dispose of instances of my Entity Framework repository classes and I created a base class to enforce this implementation. 我被告知我需要处理我的Entity Framework存储库类的实例,并创建了一个基类来强制执行此实现。

I need to check with the experts: is it acceptable to implement IDisposable through a base class? 我需要咨询专家:通过基类实现IDisposable是否可以接受?

Note that the repository class has no class member variables. 请注意,存储库类没有类成员变量。

/// 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);
    }
}

The answer is "it depends". 答案是“它取决于”。

If the "Dispose()" method in some superclass is sufficient, you certainly don't need to reimplement it in each and every subclass. 如果某个超类中的“Dispose()”方法足够,那么你肯定不需要在每个子类中重新实现它。

The "superclass" might be the base class; “超类”可能是基类; it might be one or more subclasses. 它可能是一个或多个子类。

It depends on what you allocate, and what needs to be cleaned up. 这取决于您分配的内容以及需要清理的内容。

IMHO... 恕我直言...

Here is what MSDN has to say: 这是MSDN所说的:

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

When you derive from a disposable type, and that derived type does not introduce any new resources, then nothing special needs to be done. 当您从一次性类型派生,并且派生类型不引入任何新资源时,则不需要做任何特殊处理。 The base type IDisposable implementation will take care of cleaning up its resources and your subclass can be blissfully ignorant of the details. 基本类型IDisposable实现将负责清理其资源,您的子类可能会对细节一无所知。

<= In other words, you DON'T necessarily have to re-implement Dispose over and over <=换句话说,您不必一遍又一遍地重新实现Dispose

... but ... ......但......

However, it's also common to have a subclass that does contain new resources that need to be cleaned up. 但是,拥有一个包含需要清理的新资源的子类也很常见。 In this case, your class needs to release its resources, while making sure that the base type's resources also get released. 在这种情况下,您的类需要释放其资源,同时确保基类型的资源也被释放。 Do this by overriding the cleanup method, releasing your resources, and then calling the base type to clean up its resources, as in Figure 6. 通过重写清理方法,释放资源,然后调用基类型来清理其资源来完成此操作,如图6所示。

It depends on whether you have resources in the derived class that need to be disposed. 这取决于您是否在派生类中有资源需要处理。 If there are resources specific to the derived class, implementing IDisposable only on the base class will not be sufficient. 如果存在特定于派生类的资源,则仅在基类上实现IDisposable是不够的。

Generaly spoken, you have to implement IDispoable in every class, where you have private members which themselves implement IDisposable. 一般来说,你必须在每个类中实现IDispoable,你有私人成员,他们自己实现IDisposable。 Those resources have to be "freed". 这些资源必须“释放”。 I strongly advise you to read this very good paper on CodeProject about the IDisposable pattern. 我强烈建议您阅读关于IDisposable模式的CodeProject上这篇非常好的论文。

NO . 不。 you have also in sub classes. 你也有子课程。

if you wont , the GC still need to map its child's as un-referenced - and THEN to collect them... so you didn't earn nothing. 如果您不习惯,GC仍然需要将其子项映射为未引用 - 然后收集它们......所以您没有获得任何收益。

it is fine to dispose using a base class. 使用基类进行处理是可以的。 the important thing here is cleaning up unmanaged resources, which in this case means closing database connections. 这里重要的是清理非托管资源,在这种情况下意味着关闭数据库连接。 i'd argue that you'd be better off hooking into asp.net with things like httpmodules or action filters to handle your unit of work and do the dispose for a unit-of-work-per-request type of setup, but if you are instead just making sure to call dispose on your repository instances, having a base class that disposes entity framework context is fine (and you could still use the base class for these repositories even with disposing them with a filter/module). 我认为你最好通过httpsodules或动作过滤器等​​方式连接到asp.net来处理你的工作单元并为每个请求的工作单元类型的设置进行处理,但是如果您只需确保在存储库实例上调用dispose,具有处理实体框架上下文的基类就可以了(即使将它们与过滤器/模块一起使用,您仍然可以使用这些存储库的基类)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM