2013-03-07 58 views
2

我正在設計一個訪問存儲在數據庫中的一些數據的WCF服務。正確設計訪問數據的WCF服務

實際對數據庫的訪問由一些ORM層處理(目前爲NHibernate,但這是一個實現細節)。

我想知道什麼是這種情況下適當的設計?

天真的做法是這樣的:

public class ServiceImplementation : IService 
{ 
    // NHibernate session 
    private ISession session; 

    // service methods that use *session* 
} 

這是專門耦合到NHibernate和強制服務類管理的初始化和擁有的ORM邏輯代碼。

我的問題是特別:

  • 我如何實現解耦設計,其中業務從DB/ORM層分離?
  • 應該初始化數據庫訪問/ ORM層?服務是否管理?

由於這是一個很常見的情況,我假設存在一些「模式」/最佳實踐。

大多數可在線獲得的示例演示瞭如何實現這一點(如何使用ORM訪問數據庫等),而不是從設計的角度來看,如何在更大範圍內正確地完成這些操作。

回答

1

假設你希望只初始化一次,你可能要考慮建立你的服務實現類具有以下屬性:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)] 

這將導致你的服務保留在內存中的單個實例,多呼叫者都訪問該實例。缺點是你的代碼必須是線程安全的;此外,您將無法通過第二個WCF服務進行調用(爲此,您需要Reentrant併發性)。

但是,在這種情況下,您可以在您的服務中持有一個控制事物的DB/ORM端的類實例,實現您希望的解耦。

DB/ORM的初始化可以在服務的構造函數中執行。

請注意,使用包含DB/ORM功能的靜態成員變量是不明智的。這是因爲即使靜態值可能會被服務主機回收給定足夠長時間的不活動狀態。

這當然只有一種方法可以實現你想要的:你可以從檢查多重初始化與P.I.A的成本中受益。編寫線程安全代碼。一個折中的辦法是使用InstanceContextMode.PerSession - 一個用戶會話然後只會初始化ORM一次,如果用戶可能進行多次調用,則會減少初始化次數。定義和控制會話的開銷最多隻是一個小小的刺激,而且在我已經漫遊了多久的情況下,這個超出了這個響應的範圍。

+0

我已經將ContextMode設置爲單個(不確定它是否是最理想的選擇)。在我的服務中保持NHibernate的類實例如何實現分離設計? – 2013-03-07 18:08:21

+0

如果您創建了一個類並將所有ORM初始化代碼放入其中,並根據需要進行查詢,則會實現解耦。 – 2013-03-07 18:15:10