我正在尝试使用 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();
whereProxyHelper.GetProxyType<Pet>()
将返回缓存的 Pet 代理类型。主要缺点是该解决方案不适用于通用列表(例如IList<Pet>
)。我正在尝试清理的现有系统广泛使用它们。
因此,我希望是否有人对我正在做的事情是否可取有任何解决方法或任何见解。
太感谢了,
卡洛斯