"CA2000: Dispose object before losing scope" 构建 Unity 容器

"CA2000: Dispose object before losing scope" building Unity container

我使用以下代码得到 fxCop voilation CA2000: Dispose object before losing scope:

private static IUnityContainer BuildContainer()
{
   var container = new UnityContainer().LoadConfiguration();
   return container;
}

为了消除这种违规行为,我使用了以下代码:

   private static IUntyContainer BuildContainer()
    {
        using(var container = new UnityContainer())
        {
           return container.LoadConfiguration();
        }
    }

但是此代码在解析依赖项时开始抛出异常。

有人可以帮我解决这个问题吗?

这种违规行为通常源于几个代码模式,但您应该查看 Help page for CA2000 以获取更多信息

  • 工厂方法
  • 方法链接
  • 异常处理缺失或不正确

对于没有其他问题的纯工厂方法,在某些情况下,重命名方法可能就足够了。我不知道规则要查找的前缀是什么,但您可以尝试 ConstructCreateNewBuild(您拥有的那个)。

然而,就 CA2000 而言,这并不是此方法的问题。

那么让我们看一下有问题的代码:

var container = new UnityContainer().LoadConfiguration();

这里我假设 LoadConfiguration 是一个方法,returns 调用它的实例相同,用于方法链接,一个流畅的接口。

换句话说,该方法看起来有点像这样:

public class UnityContainer
{
    public UnityContainer LoadConfiguration()
    {
        // load
        return this;
    }
}

代码分析引擎现在看到这段代码:

var temp = new UnityContainer();
var container = temp.LoadConfiguration();
return container;

temp 怎么了?它无法检测到(请参阅下面我的注释)它是同一个实例,因此它认为您在这里丢失了 temp 实例,应该将其处理掉。

好的,那么将代码更改为:

var container = new UnityContainer();
container.LoadConfiguration();
return container;

现在我又犯了同样的规则:

CA2000: In method 'Program.BuildContainer()', object 'container' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'container' before all references to it are out of scope. ConsoleApplication31 C:\Dev\VS.NET\ConsoleApplication31\ConsoleApplication31\Program.cs 18 Active

基本上,代码分析引擎现在想知道如果 LoadConfiguration 抛出异常会发生什么,然后您将泄漏从未返回的临时容器对象。

所以这是此方法的 "fixed" 版本:

var container = new Container();
try
{
    container.LoadConfiguration();
    return container;
}
catch (Exception) // NOTE!
{
    container.Dispose();
    throw;
}

注意!:只处理你知道或认为LoadConfiguration可以抛出的特定异常,不要处理Exception.

注意:当我在上面说"fail to detect"时,并不意味着代码分析引擎有代码来检测失败或有错误, 它也可能意味着该规则根本没有进行那么深入的分析,例如查看 LoadConfiguration 方法并确定它总是 returns this.