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
.