2012-03-27 36 views
0

我做的事情最近被認爲是可怕的,但我個人喜歡這種實驗。這裏有一個電報風格描述:代理NHibernate對象與城堡DynamicProxy燕子NH功能

  • 使用NH來獲取數據對象
  • 每個數據對象由CastleDynamicProxy包裹
  • 當裝飾,帶有自定義屬性屬性進行查詢,重定向到自己的代碼,而不是NHibernate的獲取返回值。

對象創建/取數據代碼

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的環境(在cod中創建對象e,對象擁有自己的數據)。 不幸的是,Intercept方法中的else部分似乎讓NHibernate不起作用,它似乎將_wrappedObject簡化爲基本類型功能(而不是由NHibernate代理),因此所有映射的Child集合都保留爲空。

我試着從lazy切換到eager加載(並確認所有的SQL都被執行),但是根本沒有任何改變。

有沒有人有一個想法,我可以做些什麼來恢復工作?

非常感謝!

回答

1

我發現我做的是部分錯誤,部分不完整。與其刪除這個問題,我選擇自己回答,以便其他人也可以從中受益。

首先,我誤解了類代理是一個實例代理,這就是爲什麼我存儲了_wrappedObject。我需要該對象執行invocation.Method.Invoke(_wrappedObject, invocation.Arguments),這是下一個錯誤。而不是這樣做,我應該通過使用invocation.Proceed()將呼叫傳遞給下一個攔截器。

現在,那裏不完整? NH似乎需要知道有關的元數據是實例,所以我錯過了一個重要的線,使NH注意,代理是它的近親之一:

SessionFactory.GetClassMetadata(entityName).SetIdentifier(instance, id, entityMode); 

在NHibernate的攔截這隻作品,因此最終產品的不同從我最初的那一點...有點亂碼,你可以在Ayende的website上看到一個非常非常理解的例子。他的偉大教程大道具!