現在、CodeContracts を既存のコード ベースに追加する作業を行っています。
難しいことの 1 つは、NHibernate によってハイドレートされたエンティティの使用です。
次の単純なクラスを想定します。
public class Post
{
private Blog _blog;
[Obsolete("Required by NHibernate")]
protected Post() { }
public Post(Blog blog)
{
Contract.Requires(blog != null);
_blog = blog;
}
public Blog Blog
{
get
{
Contract.Ensures(Contract.Result<Blog>() != null);
return _blog;
}
set
{
Contract.Requires(value != null);
_blog = value;
}
}
[ContractInvariantMethod]
private void Invariants()
{
Contract.Invariant(_blog != null);
}
}
このクラスは、不変式を保護しようとし_blog != null
ます。Post
ただし、それから派生して保護されたコンストラクターを使用することで、 のインスタンスを簡単に作成できるため、現在は失敗しています。その場合_blog
は になりますnull
。
不変条件が実際に保護されるようにコードベースを変更しようとしています。
保護されたコンストラクターは、NHibernate が新しいインスタンスを作成できるようにするために一見必要ですが、この要件を回避する方法があります。
そのアプローチは基本的にを使用しFormatterServices.GetUninitializedObject
ます。重要な点は、このメソッドがコンストラクターを実行しないことです。
このアプローチを使用すると、保護されたコンストラクターを取り除くことができます。CodeContracts の静的チェッカーはこれで満足し、それ以上の違反を報告しなくなりますが、NHibernate がそのようなエンティティをハイドレートしようとするとすぐに、「不変の失敗」例外が生成されます。不変条件を検証するコード。
したがって、これらすべてを機能させるには、パブリック コンストラクターを介してエンティティをインスタンス化する必要があります。
しかし、どうすればこれを行うことができますか?