我最近做了一些被认为太可怕的事情,但我个人很喜欢这种实验。这是电报风格描述:
对象创建/数据获取代码
Objects=GetAll().Select(x=>ProxyFactory.CreateProxy<T>(x)).ToList();
public IList<Person> GetAll()
{
ISession session = SessionService.GetSession();
IList<Person> personen = session.CreateCriteria(typeof(Person))
.List<Person>();
return personen;
}
代理生成代码:
public T CreateProxy<T>(T inputObject)
{
T proxy = (T)_proxyGenerator.CreateClassProxy(typeof(T), new ObjectRelationInterceptor<T>(inputObject));
return proxy;
}
使用的拦截器定义如下:
public class MyInterceptor<T> : IInterceptor
{
private readonly T _wrappedObject;
public MyInterceptor(T wrappedObject)
{
_wrappedObject = wrappedObject;
}
public void Intercept(IInvocation invocation)
{
if (ShouldIntercept(invocation)) { /* Fetch Data from other source*/ }
else
{
invocation.ReturnValue = invocation.Method.Invoke(_wrappedObject, invocation.Arguments);
}
}
public bool ShouldIntercept(IInvocation invocation)
{
// true if Getter / Setter and Property
// has a certain custom attribute
}
}
这在没有NHibernate的环境中工作正常(在代码中创建对象,其中Object拥有自己的数据)。
不幸的是,else
在侦听方法部分似乎离开NHibernate的未官能化,似乎_wrappedObject
减小到它的基本类型的功能(而不是由NHibernate的被代理),所以所有映射的子集保持为空
我尝试从lazy
切换到eager
加载(并确认所有SQL都已执行),但这根本不会改变任何内容。
有人知道我能做些什么才能恢复工作吗?
提前多多感谢!
答案 0 :(得分:1)
我发现我所做的是部分错误而且部分不完整。我没有删除这个问题,而是选择自己回答,以便其他人也可以从中受益。
首先,我误解了类代理是一个实例代理,这就是我存储_wrappedObject
的原因。我需要Object来执行invocation.Method.Invoke(_wrappedObject, invocation.Arguments)
,这是下一个错误。我应该通过使用invocation.Proceed()
将调用传递给下一个拦截器而不是这样做。
现在,不完整的地方在哪里? NH似乎需要知道有关它的实例的元数据,所以我错过了一条重要的路线,让NH知道代理是其亲属之一:
SessionFactory.GetClassMetadata(entityName).SetIdentifier(instance, id, entityMode);
这只适用于NHibernate拦截器,因此最终产品与我最初的产品略有不同......足够的胡言乱语,你可以在Ayende的website上看到一个非常易于理解的例子。他的精彩教程的大道具!