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

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

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

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

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

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

有人可以帮我弄这个吗?

此违规通常源于一些代码模式,但您应该查看CA2000的“ 帮助”页面以获取更多信息

  • 工厂方法
  • 方法链
  • 缺少或不正确的exception处理

对于没有其他错误的纯工厂方法,在某些情况下可能只需重命名该方法即可。 我不知道规则要求的前缀是什么,但你可以尝试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()’中,对象’container’未沿所有exception路径放置。 在对对象’容器’的所有引用超出范围之前调用System.IDisposable.Dispose。 ConsoleApplication31 C:\ Dev \ VS.NET \ ConsoleApplication31 \ ConsoleApplication31 \ Program.cs 18活动

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

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

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

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

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