2008-12-19 39 views
3

我是一名學生,目前在使用Nhibernate + WCF + WPF的.net n-tier應用程序中進行遊戲。遍歷來自n層客戶端的對象圖

其中一件事做得相當可怕是對象圖形序列化,實際上它根本沒有做,目前關聯被忽略,我們在各處都使用DTO。

據我所知,一種方法是預先定義哪些對象和集合應該加載並序列化以穿過網絡,從而能夠向客戶端呈現一些關聯,但是這看起來有限,不靈活並且不一致(你能否告訴我不喜歡這個想法)。

發生在我身上的一個選擇是簡單地用客戶端層上的延遲加載收集替換爲「disconnectProxy」的NHProxies,它將通過線路檢索關聯的東西。這意味着我們必須稍微擴展我們的Web服務簽名,並對我們生成的代理進行一些修改,但這看起來像是一個很好的T4 /其他代碼生成實驗。

據我所知,這似乎是一個常見的絆腳石,但經過大量的閱讀後,我一直無法找出任何好的/普遍接受的解決方案。我正在尋找與任何特定解決方案相同的方向,但如果有一個簡單的方法可以讓客戶「感受」連接,請告訴我。

回答

1

對我來說這已經有一段時間了,但注入/斷開的代理服務器可能並不像聽起來那麼糟糕。既然你是一個學生,我會假設你有一些時間,並且想要琢磨一下。

如果你想注入你自己的自定義序列化/反序列化邏輯,你可以使用IDataContractSurrogate,它可以使用DataContractSerializerOperationBehavior來應用。我只做了一些基本的事情,但這可能值得研究。通過在這一層增加一些有趣的邏輯(閱讀:潛在的黑客),你可能會使它更加連接。

Here是一個關於來到同一實現的人的MSDN帖子,NHibernate使用的DynamicProxy使得不可能直接序列化進行延遲加載的NHibernate對象。

6

你問一個很好的問題,不幸的是沒有一個很乾淨的答案。即使您可以通過WCF(我們可以做到這一點)獲得延遲加載,但使用代理攔截器仍然會遇到問題。請相信我,您需要客戶端層上的POCO對象!

你確實需要考慮什麼...什麼被視爲行業標準的做法,從我所看到的研究這個問題,被稱爲持久性與使用持久性的無知。換句話說,您的對象模型和映射表示您的持久域,但它不符合您的理想使用場景。你不想把整個數據庫放到客戶端只是爲了顯示一些屬性?

看起來像這樣一個簡單的問題,但解決方案要麼非常簡單,要麼非常複雜。一方面,您可以圍繞您的使用場景設計您的實體,但最終會導致對象域的擴散,從而難以維護。另一方面,您仍然需要豐富的對象模型關係來編寫精細的業務邏輯。

爲了簡化這個問題,我們來看看我們需要填補的兩個主要缺陷......數據庫與數據庫/服務層之間以及服務與客戶端之間的差距。通過提供一個ORM來將數據加載到對象中,NHibernate填補了第一個空白。它做的不錯,但爲了實現出色的性能,需要使用自定義加載策略進行調整。我離題...

服務器和客戶端之間的第二個鴻溝就是事情變得危險的地方。爲了簡化,想象一下,如果你沒有通過線路發送任何映射實體給客戶端?嘗試創建一個將業務實體交換爲DTO對象的機制,並將DTO對象同樣轉換爲業務實體。這樣你的客戶只處理DTO(當然是POCO),你的業務邏輯可以保持其豐富的結構。這使您不僅可以利用NHibernate的延遲加載機制,還可以利用會話的其他好處,如L1緩存。

由於簡潔和知識產權的原因,我不會進入上述機制的設計,但希望這是足夠的信息指向你在正確的方向。如果你根本不關心性能或延遲......只需將所有延遲加載關閉在一起,並解決序列化問題。

0

如果你真的決心通過網絡傳輸對象圖並保留延遲加載功能。看看我在這裏製作的一些代碼http://slagd.com/?page_id=6。基本上它會在電線的另一端創建一個假會話,並允許nhibernate代理保留其功能。不要說這是做事的正確方式,但它可能會給你一些想法。