“ CA2000:在失去作用域之前处置对象”。建立Unity容器 [英] "CA2000: Dispose object before losing scope" building Unity container

查看:136
本文介绍了“ CA2000:在失去作用域之前处置对象”。建立Unity容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码来获取fxCop变形CA2000:在失去作用域之前处理对象:

 私有静态IUnityContainer BuildContainer ()
{
var container = new UnityContainer()。LoadConfiguration();
个返回容器;
}

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

 私有静态IUntyContainer BuildContainer()
{
using(var container = new UnityContainer())
{
return container.LoadConfiguration();
}
}

但是这段代码在解决依赖关系时开始抛出异常。 / p>

有人可以帮我吗?

解决方案

这种侵犯通常会根源两种代码模式中的内容,但是您应该查看 CA2000的帮助页面有关更多信息




  • 工厂方法

  • 方法链接

  • 缺少或不正确的异常处理



对于没有其他错误的纯工厂方法,在某些情况下只需重命名方法。我不知道规则要查找的前缀是什么,但是您可以尝试构造创建新建构建(您拥有的一个)。



此但是,就CA2000而言,此方法并不是什么问题。



因此,让我们看一下相关代码:

  var容器= new UnityContainer()。LoadConfiguration(); 

在这里,我假设 LoadConfiguration 是一种方法,它返回与调用它时所用的实例相同的实例(用于方法链接),使接口流畅。



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

 公共类UnityContainer 
{
public UnityContainer LoadConfiguration()
{
//加载
返回此值;
}
}

代码分析引擎现在看到以下代码:

  var temp = new UnityContainer(); 
var container = temp.LoadConfiguration();
个返回容器;

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



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

  var container = new UnityContainer (); 
container.LoadConfiguration();
个返回容器;

现在,根据相同的规则,我又遇到了另一次违规:


CA2000 :在方法'Program.BuildContainer()'中,对象'container'并未沿所有异常路径放置。在对对象容器的所有引用超出范围之前,请调用System.IDisposable.Dispose在对象容器上。 ConsoleApplication31 C:\Dev\VS.NET\ConsoleApplication31\ConsoleApplication31\Program.cs 18 Active


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



因此,此方法是固定版本:

  var container = new Container(); 
try
{
container.LoadConfiguration();
个返回容器;
}
catch(Exception)//注意!
{
container.Dispose();
投掷;
}

注意!:仅处理您的特定例外知道或认为 LoadConfiguration 会抛出,不处理 Exception



注意:当我在上面说未能检测到时,并不表示代码分析引擎具有适当的代码来检测此失败或有错误,它可以也意味着该规则不会深入分析,例如查看 LoadConfiguration 方法并确定其始终返回 this


I am using following code where I am getting fxCop voilation CA2000: Dispose object before losing scope:

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

to remove this violation I have used following code:

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

But this code start throwing exception while resolving dependencies.

Can someone help me with this?

解决方案

This violation usually stems from a couple of code patterns though you should look at the Help page for CA2000 for more information

  • Factory methods
  • Method chaining
  • Missing or incorrect exception handling

For pure factory methods that have nothing else wrong it may in some cases be enough to just rename the method. I don't know what the prefixes the rule is looking for are but you can try Construct, Create, New, Build (the one you have).

This, however, is not what is wrong with this method in terms of CA2000.

So let's look at the code in question:

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

Here I am going to assume that LoadConfiguration is a method that returns the same instance as it is invoked on, for method chaining, a fluent interface.

In other words the method looks somewhat like this:

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

The code analysis engine now sees this code:

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

What happened to temp? It fails to detect (see my note below) that it is the same instance so it thinks you lost the temp instance here, and this should be disposed.

OK, so how about changing the code to this:

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

Now I get another violation, from the same rule:

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

Basically the code analysis engine now wonders what happens if LoadConfiguration throws an exception, then you would leak the temporary container object that was never returned.

So here is the "fixed" version of this method:

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

NOTE!: Only handle the specific exceptions you know or think that LoadConfiguration can throw, don't handle Exception.

Note: When I say "fail to detect" above it doesn't mean that the code analysis engine has code in place to detect this that either fails or has a bug, it can also mean that the rule simply doesn't do that deep of an analysis, such as looking at the LoadConfiguration method and determining that it always returns this.

这篇关于“ CA2000:在失去作用域之前处置对象”。建立Unity容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆