2010-08-05 1 views
2

WPF 컨트롤 프로젝트에서 코드 계약을 활성화하면 컴파일 타임에 생성 된 자동 생성 파일 (XamlNamespace.GeneratedInternalTypeHelper)에 문제가 발생했습니다. 생성 된 파일의 이름은 GeneratedInternalTypeHelper.g.cs이며 GeneratedInternalTypeHelper.g.i.cs와는 다르며 여기에는 몇 가지 오래된 블로그 게시물이 있습니다.코드 계약 및 자동 생성 파일

그 목적이 정확히 무엇인지 모르겠지만 XAML을 해결하기 위해 내부 반영이 중요하다고 가정합니다. 문제는 코드 계약이 없으며 코드 계약 시스템이 자동으로 생성 된 파일로 인식 할만큼 똑똑하지 않다는 것입니다. 이로 인해 정적 검사기에서 많은 오류가 발생합니다.

이 문제에 대한 해결책을 찾으려고했지만 아무도 WPF 컨트롤을 개발하지 않고 코드 계약을 사용하고있는 것처럼 보입니다. 흥미로운 속성 인 ContractVerificationAttribute를 보았습니다.이 속성은 어셈블리 또는 클래스의 검증 여부를 설정하는 부울 값을 사용합니다. 이렇게하면 확인되지 않은 클래스를 꾸밀 수 있습니다. 안타깝게도 GeneratedInternalTypeHelper는 모든 컴파일시 다시 생성되므로이 클래스 하나만 제외 할 수는 없습니다. 반대 시나리오는 가능하지만 검증되지 않은 어셈블리를 장식 한 다음 모든 클래스를 옵트 인합니다.

[Fact] 
public void AllAssemblyTypesAreDecoratedWithContractVerificationTrue() 
{ 
    var assembly = typeof(someType).Assembly; 
    var exposedTypes = assembly.GetTypes().Where(t=>!string.IsNullOrWhiteSpace(t.Namespace) && t.Namespace.StartsWith("MyNamespace") && !t.Name.StartsWith("<>")); 

    var areAnyNotContractVerified = exposedTypes.Any(t => 
    { 
     var verificationAttribute = t.GetCustomAttributes(typeof(ContractVerificationAttribute), true).OfType<ContractVerificationAttribute>(); 
     return verificationAttribute.Any() && verificationAttribute.First().Value; 
    }); 

    Assert.False(areAnyNotContractVerified); 
} 
:

나는 적어도 그 자신의 클래스를 확인하기 위해 다음을 적어도 확인되는 것처럼 테스트에 노출 된 클래스 코드 계약 검증이 있는지 확인 할 테스트를 만들고 싶었 명백한 해킹을 완화하려면

컨트롤 어셈블리의 모든 클래스를 가져 와서 회사 네임 스페이스에서 자동 생성 된 익명 형식 (<> WeirdClassName)이 아닌 클래스를 찾습니다.

(자원 및 설정도 제외해야하지만 아이디어를 얻길 바랍니다.)

계약 확인을 피할 방법이 있으므로 솔루션을 좋아하지 않지만 현재는 내가 생각해 볼 수있는 최선의 방법입니다. 누구든지 더 나은 해결책이 있다면 알려 주시기 바랍니다.

+0

이 https://connect.microsoft.com/VisualStudio/feedback/details/483730/code-analysis-does-not-exclude-wpf-generated- 파일에 대한 의견 중 일부는 코드 분석 탭으로 이동하는 것이 좋습니다. "생성 된 코드에서 결과 억제"를 선택 해제하고 다시 확인한 후 다시 시도하십시오. 분명히 CC가 아닌 VS2010 자체의 문제입니다. – porges

답변

0

다른 "제 3 자"클래스 나 라이브러리를 다루는 것처럼이 클래스를 정확하게 처리 할 수 ​​있습니다. 특정 가정은이 생성 된 클래스와의 상호 작용을 유지하므로 상호 작용점에서 Contract.Assume(result != null) 또는 이와 유사한 코드로 장식하십시오. 이것은 무엇을

var result = new GennedClass().GetSomeValue(); 
Contract.Assume(result != null); 

런타임에 확인되는 주장으로 번역이지만, 정적 분석기 당신이 제어 할 코드의 나머지 부분에 대해 추론 할 수 있습니다.