私は何か違うことを提案します...遅延ロードクラスを使用します:
public class Lazy<T>
{
T value;
Func<T> loader;
public Lazy(T value) { this.value = value; }
public Lazy(Func<T> loader { this.loader = loader; }
T Value
{
get
{
if (loader != null)
{
value = loader();
loader = null;
}
return value;
}
public static implicit operator T(Lazy<T> lazy)
{
return lazy.Value;
}
public static implicit operator Lazy<T>(T value)
{
return new Lazy<T>(value);
}
}
一度取得したら、もうオブジェクトに dao を注入する必要はありません:
public class Transaction
{
private static readonly Lazy<Customer> customer;
public Transaction(Lazy<Customer> customer)
{
this.customer = customer;
}
public Customer Customer
{
get { return customer; } // implicit cast happen here
}
}
データベースにバインドされていないトランザクション オブジェクトを作成する場合:
new Transaction(new Customer(..)) // implicite cast
//from Customer to Lazy<Customer>..
リポジトリ内のデータベースからトランザクションを再生成する場合:
public Transaction GetTransaction(Guid id)
{
custmerId = ... // find the customer id
return new Transaction(() => dao.GetCustomer(customerId));
}
2 つの興味深いことが起こります: - ドメイン オブジェクトは、データ アクセスの有無にかかわらず使用できます。データ アクセスを無視します。唯一のちょっとしたひねりは、オブジェクト自体の代わりにオブジェクトを与える関数を渡すことができるようにすることです。- Lazy クラスは内部的に可変ですが、不変の値として使用できます。readonly キーワードは、その内容を外部から変更できないため、セマンティックを保持します。
フィールドを書き込み可能にしたい場合は、単に readonly キーワードを削除してください。新しい値を割り当てると、暗黙のキャストにより、新しい値で新しい Lazy が作成されます。
編集:ここでブログを書きました:
http://www.thinkbeforecoding.com/post/2009/02/07/Lazy-load-and-persistence-ignorance