2009-07-22 69 views
13

我正在構建一個應用程序,該應用程序大致遵循存儲庫模式,頂層有一個服務層,類似於早期版本的Conery MVC店面。服務層應該可以訪問HttpContext嗎?

我需要實現一個頁面,返回除當前用戶以外的所有用戶。我已經在存儲庫和服務層上使用了GetUsers()方法,所以問題在於應用「除當前用戶之外」的位置。

服務層應該知道HttpContext,從而應用此規則嗎?我試圖將當前用戶(id)從控制器傳遞給此服務方法,但如果服務層支持HttpContext並且可以獨立執行此操作,它似乎更清晰。

一個明顯的替代方案是直接在控制器內實施該規則,但我只是不熱的這種想法......


編輯 - 只是在回答評論:我看問題與反向依賴問題,我完全忽略了一些東西。我將Mehrdad's評爲應得票數,但每個人都提供了值得一讀的寶貴回覆!

回答

18

絕對不是。我在設計這類事情時的心態是這樣的:我假設我需要編寫一個基於Windows的應用程序以及Web應用程序,並儘量減少對Web特定內容的依賴。直接傳遞HttpContext會增加服務層到您的Web UI層的耦合,這是不理想的。

4

您應該而不是創建您的服務層和Web層之間的反向依賴關係。考慮當你想擴展你的服務層來使用基於表單的應用程序或者Windows服務時會發生什麼。現在,您必須解決Web依賴關係,以使您的相同方法能夠工作或複製一些(可能很小但仍然是重複的)代碼。您可以更好地將用戶標識符提取到服務層上下文中有用的某些內容中,並將該值用於服務層。在網站上處理過濾也是可以接受的,但是如果你不止一次這樣做,它需要重構到一個普通的地方,而服務層是它的自然之處。

2

我覺得很好的做法是構建一個包含我當前用戶對象(以及其他上下文數據)的自定義AppContext類。這個類沒有對System.Web的引用。任何需要上下文感知的服務方法都應該有一個AppContext參數(例如,用於檢查安全權限,或獲取當前用戶的情況)。如果需要,在Web層中填充此對象並將其保留在會話中。這樣你的服務層對System.Web一無所知。

+0

簡單傳遞用戶標識有什麼問題? – 2009-07-22 12:30:38

+0

它根本就沒有錯,我只是喜歡以同樣的方式處理所有情境感知的情況。 – JonoW 2009-07-22 12:33:23

9

答案是,

不僅服務層不應該依賴當前的表示層,我認爲它應該不依賴於當前的應用程序。例如,我不會使用定製的AppContext類作爲JonoW建議here

而是將當前用戶作爲參數傳遞給GetAllUsersExceptForTheCurrentUser方法。這樣,任何需要處理用戶的應用程序都可以使用該服務,而不僅僅是當前應用程序。

1

否這樣做會使您的代碼更難以測試和重用。

我傾向於爲這種事情構建一個基礎結構接口(稱之爲IAuthentication或其他),並在其上公開一個CurrentUser屬性。然後,我會通過它的構造函數將其注入到我的服務中。即公共MyService(IAuthentication auth)

最後,您可以構建一個支持IAuthentication的HttpContext感知實現(比如WebAuthentication)。

現在,當你創建你的服務,你創建它的依賴,以及:

var myService = new MyService(new WebAuthentication()); 
var otherUsers = myService.GetAllOtherUsers(); 

如果您使用的是IoC容器醜陋的依賴性甚至可以走開!

相關問題