I'm making an extension to Visual Studio. Within the code I'm using Code Contracts to make assertions and checks. I set the warning option level to high.
What I would like to do is maintain that warning level while ignoring any checks made on EnvDTE references.
Consider the following code example:
public static string GetAbsoluteOutputFolder(EnvDTE.Project project)
{
if (project == null) throw new ArgumentNullException("project");
var path =
project.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString();
//...
}
With my current settings, CC would require me to add the following checks before assigning the path
variable:
Contract.Assume(project.ConfigurationManager != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration.Properties != null);
Therefore what I'd like to do here is to tell CC to "trust" EnvDTE and ignore these types and their properties.
I thought the "Be optimistic on external API" CC option served this very purpose; turns out it doesn't.
Is there a way to make it behave the way I want that would not require a lower warning level?
EDIT: I want a solution that would work at project level and that would still allow "regular" checks to be performed.
Can´t provide a detailed solution but this should be solvable by using either the Baseline Feature or System.Diagnostics.CodeAnalysis.SuppressMessage on assembly level:
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Contracts", "Whatever")]
You can use the "Target" Property of the SuppressMessageAttribute to only ignore the Message on specific Types / Methods / Namespaces:
[SuppressMessage("Microsoft.Contracts",
"CC1055",
Scope="Member",
Target="YouNamespace.EnvDTE.Project")]
Note that the Parameters i used are just a good bet, you´ll have to figure out the correct Scope, MessageId and Target yourself :) On a sidenote, i think the Attribute is Conditional("CODE_ANALYSIS").
The official suggested solution to this problem is to create some sort of wrapper, in your case probably a repository that would create or contain your EnvDTE.Project objects. Then you can add the required Contract.Ensures there.
I don't think it's possible to solve the problem but since C# 6.0 there is a workaround which at least eases the pain a bit:
Instead of
Contract.Assume(project.ConfigurationManager != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration.Properties != null);
you can now write
Contract.Assume(project.ConfigurationManager?.ActiveConfiguration?.Properties != null);
Have you tried something with :
[assembly: Contracts.ContractVerification(false)]
at the assembly level ?
You should be able to do it dynamically : https://msdn.microsoft.com/en-us/library/bb458043.aspx
Hope this helps,
来源:https://stackoverflow.com/questions/25568707/how-can-i-make-code-contracts-ignore-a-specific-assembly-reference