2013-07-02 122 views
7

我正在使用.NET 4爲客戶創建一個小型客戶端服務器應用程序。我應該創建一個實現許多合同(IInvoice,IPurchase,ISalesOrder等)的巨型服務,還是應該在許多端口上創建運行一個合同的許多服務?我的問題特別是對任何選擇的利弊感興趣。另外,回答這個問題的常見方法是什麼?wcf決定:一個服務多個合同或許多服務

我的真正困境是,我沒有經驗做出這個決定,而且我對wcf的經驗也不多,因此我需要幫助理解這種決定的技術含義。

回答

4

不要創建一個實現n個服務合約的大型服務。這些類型的服務很容易創建,但最終會成爲維護頭痛,並且不能很好地擴展。另外,如果有開發組競爭簽入/簽出,你會得到各種各樣的代碼合併衝突。

不要創建太多的服務。避免讓服務過於細化的陷阱。嘗試基於功能創建服務。這些服務暴露的方法也不應該是細粒度的。你最好少做更多的方法。避免通過創建GetUser(userObject用戶)來創建類似的函數,如GetUserByID(int ID),GetUserByName(string Name)。您將擁有更少的代碼,更輕鬆的維護和更好的可發現性。

最後,無論你做什麼,你都可能只需要一個端口。

+0

如果使用部分類/接口文件來避免合併衝突,那麼參數「不能很好地擴展」呢?這在技術上意味着什麼? – Askolein

+0

@Askolein ......這意味着如果你在一份合同中填充太多,它可能會成爲性能瓶頸以及維護/擴展性問題。 –

+2

感謝您的回答,但我的問題更多的是「爲什麼」它可能是一個性能問題,而不是「什麼」是性能問題。你說「瓶頸」:我明白在ISS/WCF中,每個Web請求都是一個新的Service實例。單個大型服務的多個請求仍然是多個實例,而不是一個實例提供所有這些實例。所以沒有縮放問題。這個推理是否正確? – Askolein

1

它似乎是DataContract(s)和ServiceContract(s)之間的混合。 您可以有一個ServiceContract和許多DataContract(s),這將完全適合您的需求。

2

在實時應用中,你有喜歡的發票,購買和SalesOrder每個實體一份服務合同中都會有不同的的ServiceContract

然而,對於每一個服務合同會有異構客戶端像發票將通過後臺通過Windows應用程序調用使用netNamedPipeBinding或netTcpBinding和相同時間客戶端應用程序需要使用basicHttpBinding或wsHttpBindings調用服務。基本上你需要爲每個服務創建多個端點。

0

您應該根據預期負載,可擴展性和未來角度來做出決定。正如你寫的「面向客戶的小型客戶服務器應用程序」,它並沒有清楚地表明開發的用途。 Big先生的回答也必須考慮。

我們非常歡迎您提出進一步的問題,並提供具體的數據或有關當前情況的詳情。謝謝。

2

您通常會爲IInvoice,IPurchase,ISalesOrder等每個主要實體創建不同的服務。

另一種選擇是從命令中分離查詢。您可以爲每個主要實體提供命令服務,並實施僅接受他們執行操作所需數據的業務操作(避免類似於CRUD的操作);以及一種以客戶端所需格式返回數據的查詢服務。這意味着命令部分使用底層域模型/業務層;而查詢服務直接在數據庫上運行(繞過不需要查詢的業務)。這可以簡化您的查詢並使其更加靈活(僅返回客戶需要的內容)。

0

事實是,分離WCF服務 - 或任何服務是一種平衡行爲。原則是你想在考慮業績的同時保持複雜性的下行壓力。

您創建的服務越多,您需要編寫的配置就越多。此外,您還將增加需要在客戶端創建和維護的代理類的數量。

將太多ServiceContracts放在一個服務上會增加生成和使用代理所花費的時間。但是,如果您最終只得到一個或兩個運營合同,那麼您將會增加系統的複雜性,而且幾乎沒有什麼收穫。這不是一個科學的處方,但可以說每服務合同10-20 OperationContracts一個好的經驗法則。

類耦合當然是一個考慮因素,但是你真的在處理單獨的問題嗎?這取決於你的系統做什麼,但大多數系統只處理少數幾個領域的問題,所以分解事情實際上可能不會實際上減少類耦合。

要記住的另一件事,這是非常重要的是總是讓你的方法儘可能通用。出於某種原因,WCF在DataContracts中進行交易。 DataContracts意味着只要DataContracts是已知的,您就可以向服務器發送任何對象或從服務器發送對象。

因此,舉例來說,你可能有3個OperationContracts:

[OperationContract] 
Person GetPerson(string id); 

[OperationContract] 
Dog GetDog(string id); 

[OperationContract] 
Cat GetCat(string id); 

但是,只要這些都是已知類型的,你可以像合併這些到一個操作:

[OperationContract] 
IDatabaseRecord GetDatabaseRecord(string recordTypeName, string id); 

最終,這是設計服務合同時要考慮的最重要的事情。如果您使用DataContract序列化(如序列化方法),則適用於REST。

最後,每隔幾個月回顧一下您的ServiceContracts並刪除未被客戶使用的操作。這是另一個大的!