Castle.DynamicProxy2 を使用して、NHibernate 永続クラス内のコードをクリーンアップしようとしています。これがその単純なバージョンです。
ペットクラス:
public class Pet
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
そしてそのマッピングファイル:
<class name="Pet" table="Pet">
<id name="Id" column="Id" unsaved-value="0">
<generator class="native"/>
</id>
<property name="Name" column="Name"/>
<property name="Age" column="Age"/>
</class>
Pet クラスのインスタンスを監査する必要があります。通常、プロパティ Name と Age は自動プロパティではなく、値の変更を記録するロジックが含まれます。現在、プロキシを使用してプロパティ セッター内に監査ロジックを挿入することを考えています。そのために、Auditor IInterceptor を作成しました。
public class Auditor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
// Do something to record changes
invocation.Proceed();
}
}
Castle.DynamicProxy2 を使用して Pet クラスの監査済みインスタンスを作成するのは簡単です。
Pet aPet = proxyGenerator.CreateClassProxy<Pet>(new Auditor());
aPet.Name = "Muffles"; // The Auditor instance would record this.
aPet.Age = 4; // and this too...
ここで問題が発生します。Pet は永続化されるため、システムは NHibernate を介してフェッチされた Pet のインスタンスで動作する必要があります。私がやりたいことは、NHibernate が次のように Pet プロキシのインスタンスを自動的に返すことです。
// I would imagine an instance of Auditor being created implicitly
ICriteria criteria = session.CreateCriteria(typeof(Pet));
criteria.Add(Expression.Expression.Eq("Name", "Muffles"));
// return a list of Pet proxies instead
// so changes can be recorded.
IList<Pet> result = criteria.List<Pet>();
Pet aPet = result[0];
aPet.Age = aPet.Age + 1;
// I expect this to succeed since the proxy is still a Pet instance
session.Save(aPet);
私はそれを回避するためにこのようなことを考えました:
ICriteria criteria = session.CreateCriteria(ProxyHelper.GetProxyType<Pet>());
criteria.Add(Expression.Expression.Eq("Name", "Muffles"));
// use List() instead of List<T>()
// and IList instead of IList<Pet>
IList results = criteria.List();
キャッシュされProxyHelper.GetProxyType<Pet>()
た Pet プロキシ タイプを返します。主な欠点は、このソリューションが一般的なリスト (例: IList<Pet>
) では機能しないことです。私がクリーンアップしようとしている既存のシステムは、それらを広範囲に利用しています。
だから、誰かが回避策や、私がやっていることが賢明かどうかについての洞察を持っていることを願っています.
どうもありがとう、
カルロス