Dispose() 和 Ninject 的指南

33

所以,我有一个从 WCF 服务暴露出来的方法如下:

public GetAllCommentsResponse GetAllComments(GetAllCommentsRequest request)
{
    var response = new GetAllCommentsResponse();

    using(_unitOfWork)
        try
        {
            Guard.ArgNotNull(request, "request");

            var results = _unitOfWork.CommentRepository.Get(d => d.Id > 0).ToArray();

            //... Do rest of stuff here
        }
        catch (Exception ex)
        {
            response.Success = false;
            response.FailureInformation = ex.Message;
            Logger.LogError("GetAllComments Method Failed", ex);
        }

    return response;
}
我有一个全局DataUnitOfWork对象(它实现了IDisposable接口),当服务调用发生时,通过构造函数参数由Ninject实例化。调试时,如果我使用

using(_unitOfWork)

_unitOfWork对象在超出范围后立即被处理,然后由Ninject再次调用(尽管已被标记为处理,因此不会发生任何事情)。如果没有using语句,Ninject将处理处理。

长话短说,这方面是否有一个一般的经验法则?在我读到的所有内容都表明从来不使用它或在某些古怪的情况下使用它之后,我对整个IDisposable感到害怕,但它总是让我感到困惑。

任何输入都将不胜感激。

哦,在我打字的同时,为什么在处理时会调用GC.SuppressFinalize()?Dispose和Finalize有什么区别?


在类中实现Dispose模式时,应该将其与Finalize方法一起使用。Dispose方法可以手动释放资源,而Finalize方法则可以作为后备交换机在垃圾回收期间释放资源。同时,为了确保及时释放资源和避免重复释放,Dispose方法通常会调用GC.SuppressFinalize方法来禁用Finalize方法的调用。 - Nate222
SuppressFinalize 告诉 GC 系统:“当您确定对象是垃圾并且我们已经通过某人显式调用 Dispose 进行了清理时,请不要担心调用 Finalize。如果您不这样做,对象将保留在终结器队列中,并且 Dispose 将再次从终结器线程调用。” - Ruben Bartelink
1个回答

54

CLR文档说明,创建可释放对象的人负责调用Dispose。在这种情况下,对象是由Ninject创建的。这意味着你不应该显式地调用Dispose。

Ninject会处理除InTransientScope之外的所有其他作用域的每个可释放对象一旦与所创建对象绑定的作用域对象被GC收集,就会进行处理。这就是为什么每个可释放对象都应该使用一个非InTransientScope()的作用域进行绑定Bind。例如,你可以使用NamedScope扩展中的InParentScope(),它将在注入的对象被垃圾回收时立即处理该对象。


2
这意味着在InRequestScope中,IDisposable对象将在请求结束时被处理? - AgentFire
是的,假设您已经做了一切正确的事情,包括使用OncePerWebRequest模块。 - Adam Tegen
据我所知,Ninject 也从未释放 InSingletonScope。 - trampster
4
当内核被释放时,InSingletonScope会被释放。https://github.com/ninject/ninject/wiki/Object-Scopes以下代码应该有效:using(IKernel kernel = new StandardKernel()) { .... } - zidik
2
值得注意的是,“InTransientScope” 是在没有提供范围时的默认范围:https://github.com/ninject/Ninject/wiki/Object-Scopes - Sharpiro

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