使用Castle DynamicProxy吞咽NH功能代理NHibernate对象

使用Castle DynamicProxy吞咽NH功能代理NHibernate对象,nhibernate,proxy,interceptor,castle-dynamicproxy,Nhibernate,Proxy,Interceptor,Castle Dynamicproxy,我最近做了一些被一些人认为是可怕的事情,但我个人喜欢这种实验。以下是电报式的描述: 使用NH获取数据对象 每个数据对象都由CastleDynamicProxy包装 查询用自定义属性修饰的属性时,重定向到自己的代码而不是NHibernate以获取Returnvalue。 对象创建/数据获取代码 Objects=GetAll().Select(x=>ProxyFactory.CreateProxy<T>(x)).ToList(); public IList<Person&g

我最近做了一些被一些人认为是可怕的事情,但我个人喜欢这种实验。以下是电报式的描述:

使用NH获取数据对象 每个数据对象都由CastleDynamicProxy包装 查询用自定义属性修饰的属性时,重定向到自己的代码而不是NHibernate以获取Returnvalue。 对象创建/数据获取代码

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在代码中创建对象的环境中工作得很好,对象在代码中保存自己的数据。 不幸的是,Intercept方法中的else部分似乎使NHibernate不起作用,似乎_wrappedObject被简化为它的基类型功能,而不是由NHibernate代理,因此所有映射的子集合都保持为空

我试着从延迟加载切换到快速加载,并确认所有SQL都得到了执行,但这丝毫没有改变任何事情

有人知道我该怎么做才能让它恢复工作吗


提前多谢

我发现我所做的部分是错误的,部分是不完整的。我没有删除这个问题,而是选择自己回答,这样其他人也能从中受益

首先,我误解了类代理是实例代理,这就是我存储_wrappedObject的原因。我需要这个对象来执行invocation.Method.Invoke\u wrappedObject,invocation.Arguments,这是下一个错误。我本应该使用invocation.procedure将调用传递给下一个拦截器,而不是这样做

现在,这是哪里不完整的?NH似乎需要了解有关其实例的元数据,因此我遗漏了一行重要的内容,以使NH意识到代理是其亲属之一:

SessionFactory.GetClassMetadata(entityName).SetIdentifier(instance, id, entityMode);
这只适用于NHibernate拦截器,所以最终的产品与我最初的产品有点不同…够废话了,你可以在Ayende的上看到一个非常容易理解的例子。他伟大的教程的大道具