" CA2000:在丢失范围之前处置对象"构建Unity容器

时间:2016-03-14 06:58:24

标签: c# code-analysis fxcop static-code-analysis

我正在使用以下代码,我将获得fxCop发声CA2000:在丢失范围之前处置对象:

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

删除此违规行为我使用了以下代码:

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

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

有人可以帮我这个吗?

1 个答案:

答案 0 :(得分:2)

此违规通常源于一些代码模式,但您应该查看Help page for CA2000以获取更多信息

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

对于没有其他错误的纯工厂方法,在某些情况下,可能只需重命名该方法即可。我不知道规则要求的前缀是什么,但您可以尝试ConstructCreateNewBuild(您拥有的那个)。

然而,就CA2000而言,这不是这个方法的错误。

让我们看看有问题的代码:

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

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

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

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 :在方法'Program.BuildContainer()'中,对象'容器'未沿所有异常路径放置。在对对象'容器'的所有引用超出范围之前,调用System.IDisposable.Dispose。 ConsoleApplication31 C:\ Dev \ VS.NET \ ConsoleApplication31 \ ConsoleApplication31 \ Program.cs 18 Active

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

所以这是此方法的“固定”版本:

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

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

注意:当我说上面的“检测不到”时,并不意味着代码分析引擎有代码来检测这个失败或有错误,这也意味着该规则根本不会对分析进行深入分析,例如查看LoadConfiguration方法并确定它始终返回this