I am working on a Web Api for a SPA app using .net. I get CA2000 warnings when i use instantiate an object within a method. But when I declare the same object at the class level, the CA2000 warnings disappear. From below, example 1 gives the CA2000 warning while example 2 does not. Why?
Example 1-
public class CodeGenAPIController : ApiResponseController
{
NextGenCodeGen.CodeGenerator getEndPoint(TokenManager.TokenData tokenData, int BranchId)
{
NextGenCodeGen.CodeGenerator ret = null;
lock (branchGenLock)
{
if (branchGenerators.ContainsKey(BranchId))
ret = branchGenerators[BranchId];
}
if (ret == null)
{
string services = ConfigurationValuesAPIController.GetBranchProperties(tokenData.DatabaseIdentifier, BranchId).FirstOrDefault(x => x.Key == "AvailableCodeGenServices").Value;
string[] endpoints = services.Split(new char[] { ' ', '.' }, StringSplitOptions.RemoveEmptyEntries);
if (endpoints.Length == 0)
throw new ArgumentOutOfRangeException("AvailableCodeGenServices",
string.Format("There appear to be no Code Generation Services configured for branch {0}", BranchId));
string endpoint = endpoints[0];
if (!endpoint.ToLower().EndsWith(".asmx"))
endpoint = endpoint + ".asmx";
//OBJECT INSTANTIATION INSIDE THE METHOD
ret = new My_API.NextGenCodeGen.CodeGenerator() { Url = endpoint, UseDefaultCredentials = true};**
lock(branchGenLock)
{
branchGenerators[BranchId] = ret;
}
}
return ret;
}
}
EXAMPLE 2-
public class CodeGenAPIController : ApiResponseController
{
//OBJECT INSTANTIATION OUTSIDE THE METHOD AT THE CLASS LEVEL
NextGenCodeGen.ARGenTCodeGenerator retVal = new My_API.NextGenCodeGen.ARGenTCodeGenerator();
NextGenCodeGen.CodeGenerator getEndPoint(TokenManager.TokenData tokenData, int BranchId)
{
retVal = null;
lock (branchGenLock)
{
if (branchGenerators.ContainsKey(BranchId))
retVal = branchGenerators[BranchId];
}
if (retVal == null)
{
string services = ConfigurationValuesAPIController.GetBranchProperties(tokenData.DatabaseIdentifier, BranchId).FirstOrDefault(x => x.Key == "AvailableCodeGenServices").Value;
string[] endpoints = services.Split(new char[] { ' ', '.' }, StringSplitOptions.RemoveEmptyEntries);
if (endpoints.Length == 0)
throw new ArgumentOutOfRangeException("AvailableCodeGenServices",
string.Format("There appear to be no Code Generation Services configured for branch {0}", BranchId));
string endpoint = endpoints[0];
if (!endpoint.ToLower().EndsWith(".asmx"))
endpoint = endpoint + ".asmx";
retVal = new My_API.NextGenCodeGen.CodeGenerator();
retVal.Url = endpoint;
retVal.UseDefaultCredentials = true;
lock (branchGenLock)
{
branchGenerators[BranchId] = retVal;
}
}
return retVal;
}
}
In the class case, it should trip CA2213 and not CA2000. https://msdn.microsoft.com/en-us/library/ms182328.aspx
It looks like there's a limitation of CA2213 that it can't figure out what to do with base classes that implement IDisposable. In the example below, FileIo inherits from IoBase and doesn't raise the warning. FileIo2 only implements IDisposable and does raise the warning.
public class IoBase : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
}
}
public class FileIo: IoBase
{
private Stream io = new FileStream("c:\tmp\tmp.txt", FileMode.OpenOrCreate);
}
public class FileIo2 : IDisposable
{
private Stream io = new FileStream("c:\tmp\tmp.txt", FileMode.OpenOrCreate);
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
}
}