当我在我的WPF控制项目上启用代码契约时,我遇到了一个在编译时创建的自动生成文件的问题(XamlNamespace.GeneratedInternalTypeHelper). 注意,生成的文件名为GeneratedInternalTypeHelper.g.cs,它与GeneratedInternalTypeHelper.g.i.cs不同,GeneratedInternalTypeHelper.g.i.cs中有几个过时的博客文章。
我试图寻找这个问题的解决方案,但似乎没有人开发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)。
(我还需要排除资源和设置,但我希望您能理解)。
我不喜欢这个解决方案,因为有一些方法可以避免合同验证,但目前它是我能想到的最好的方法。如果有人有更好的解决办法,请告诉我。