"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 以获取更多信息
- 工厂方法
- 方法链接
- 异常处理缺失或不正确
对于没有其他问题的纯工厂方法,在某些情况下,重命名方法可能就足够了。我不知道规则要查找的前缀是什么,但您可以尝试 Construct
、Create
、New
、Build
(您拥有的那个)。
然而,就 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
.
我使用以下代码得到 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 以获取更多信息
- 工厂方法
- 方法链接
- 异常处理缺失或不正确
对于没有其他问题的纯工厂方法,在某些情况下,重命名方法可能就足够了。我不知道规则要查找的前缀是什么,但您可以尝试 Construct
、Create
、New
、Build
(您拥有的那个)。
然而,就 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
.