“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处理
对于没有其他错误的纯工厂方法,在某些情况下可能只需重命名该方法即可。 我不知道规则要求的前缀是什么,但你可以尝试Construct
, Create
, New
, Build
(你拥有的那个)。
然而,就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
。