WPF コントロール プロジェクトでコード コントラクトを有効にすると、コンパイル時に作成された自動生成ファイル (XamlNamespace.GeneratedInternalTypeHelper) で問題が発生しました。生成されたファイルは GeneratedInternalTypeHelper.g.cs と呼ばれ、古いブログ投稿がいくつかある GeneratedInternalTypeHelper.gics と同じではないことに注意してください。
その目的が正確にはわかりませんが、内部リフレクションが XAML を解決することが重要であると想定しています。問題は、コード コントラクトがないことと、コード コントラクト システムが自動生成ファイルとして認識できるほどスマートでないことです。これにより、静的チェッカーから一連のエラーが発生します。
この問題の解決策を探してみましたが、誰も WPF コントロールを開発してコード コントラクトを使用していないようです。アセンブリまたはクラスを検証するかどうかを設定するブール値を取る、興味深い属性である ContractVerificationAttribute を見つけました。これにより、クラスを検証されていないものとして装飾できます。残念ながら、GeneratedInternalTypeHelper はコンパイルごとに再生成されるため、この 1 つのクラスだけを除外することはできません。ただし、逆のシナリオも可能です。アセンブリを検証されていないものとして装飾し、すべてのクラスをオプトインします。
明らかなハッキングを軽減するために、公開されたクラスにコード コントラクトの検証があることを少なくとも検証するテストを作成したいと考えました。次のようなテストを使用して、独自のクラスが少なくとも検証されていることを確認します。
[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) でもない会社の名前空間からクラスを見つけます。
(リソースと設定も除外する必要がありますが、理解していただければ幸いです)。
契約の検証を回避する方法があるため、私はこの解決策が好きではありませんが、現在のところ、私が思いつくことができる最善の方法です. 誰かがより良い解決策を持っている場合は、私に知らせてください。