Как я могу заставить Code Contracts игнорировать конкретную ссылку на сборку?
Я делаю расширение для Visual Studio. Внутри кода я использую Code Contracts, чтобы делать утверждения и проверки. Я установил уровень предупреждения выше.
То, что я хотел бы сделать, это поддерживать этот уровень предупреждения, игнорируя любые проверки, сделанные в ссылках EnvDTE.
Рассмотрим следующий пример кода:
public static string GetAbsoluteOutputFolder(EnvDTE.Project project)
{
if (project == null) throw new ArgumentNullException("project");
var path =
project.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString();
//...
}
С моими текущими настройками CC потребует от меня добавить следующие проверки перед назначением переменной path
:
Contract.Assume(project.ConfigurationManager != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration.Properties != null);
Поэтому мне хотелось бы сказать CC, чтобы "доверять" EnvDTE и игнорировать эти типы и их свойства.
Я подумал, что опция "Будьте оптимистичной по внешнему API" для этой цели. Оказывается, это не так.
Есть ли способ заставить его вести себя так, как я хочу , для которого не требуется более низкий уровень предупреждения?
EDIT: Я хочу решение, которое будет работать на уровне проекта, и это все равно позволит выполнять "обычные" проверки.
Ответы
Ответ 1
Невозможно предоставить подробное решение, но это должно быть разрешено с использованием либо базовой функции, либо System.Diagnostics.CodeAnalysis.SuppressMessage на уровне сборки:
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Contracts", "Whatever")]
Вы можете использовать свойство "Target" атрибута SuppressMessageAttribute, чтобы игнорировать сообщение только для определенных типов/методов/пространств имен:
[SupressMessage("Microsoft.Contracts", "CC1055", Scope="Member", Target="YouNamespace.EnvDTE.Project"]
Обратите внимание, что используемые мной параметры - это хорошая ставка, вам нужно выяснить правильную область действия Scope, MessageId и Target:). На боковой панели я считаю, что атрибут условный ( "CODE_ANALYSIS" ).
Официальное предлагаемое решение этой проблемы - создать какую-то оболочку, в вашем случае, вероятно, репозиторий, который будет создавать или содержать объекты EnvDTE.Project. Затем вы можете добавить требуемые Contract.Ensures.
Ответ 2
Я не думаю, что это возможно для решения проблемы, но поскольку С# 6.0 есть обходное решение, которое по меньшей мере облегчает боль:
Вместо
Contract.Assume(project.ConfigurationManager != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration.Properties != null);
теперь вы можете написать
Contract.Assume(project.ConfigurationManager?.ActiveConfiguration?.Properties != null);
Ответ 3
Вы пробовали что-то с:
[assembly: Contracts.ContractVerification(false)]
на уровне сборки?
Вы можете сделать это динамически: https://msdn.microsoft.com/en-us/library/bb458043.aspx
Надеюсь, что это поможет,