控制器和IDisposable

3
如果我让一个控制器实现IDisposable接口,我会认为Dispose方法不会被垃圾回收器调用。这意味着我需要添加以下代码:
public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

protected override void Dispose(bool disposing)
{
    if (!isDalDisposed)
    {
        isDalDisposed = true;
        if (disposing)
            DAL.Dispose();
    }
    base.Dispose(disposing);
}

我看到使用 Object.Finalize 是不好的做法,应该尽可能避免。

我的问题是,“服务”是在默认构造函数中创建的,这不允许我使用 using 语句来控制每个服务的生命周期。那么,处理这个问题的正确方法是什么?


你正在使用ASP.NET MVC吗? - Matthew Watson
2
你在谈论什么类型的控制器?在WebAPI中,控制器是每个请求实例化的,因此不需要显式地处理。 - Amit Kumar Ghosh
是的,我在谈论Web API控制器。我有一些服务是可处理的,并且我在构造函数中实例化它们。当它们完成时,我需要处理它们,但我正在尝试找到一种不使用finalize方法的方式来处理它们,因为我读到这是不好的做法。 - r3plica
3个回答

7

Web API的ApiController已经实现了IDisposable并提供了方便的虚拟方法供开发人员重写,这就是您正在使用的Dispose(bool)方法。因此,您所需要做的就是删除自己的布尔标志并仅检查disposing参数。

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        DAL.Dispose();
    }
    base.Dispose(disposing);
}

3
如果您可以重写protected void Dispose(bool disposing),则意味着基类使用可处理模式,并已经实现了IDisposable
只需移除IDisposable接口和public void Dispose()方法,它就可以工作。

1

为什么你要在构造函数中创建服务?是否有特定的原因?

由于控制器是每个请求实例化一次,你可以在操作方法内部使用 'using' 块来创建服务。服务的生命周期总是限定在操作中。


另一个相关的可能性是将服务工厂注入到控制器构造函数中,然后在操作中使用注入的工厂来创建服务。请注意,注入的工厂本身不应实现 IDisposable,因此不需要进行处理。(尽管如果它确实这样做了,其处置可能会成为注入器的责任。) - DavidRR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接