2009-08-24 55 views
4

我有一對夫婦與循環引用/依賴,我已經坐在了一整天的問題。我的思考過程中一定是錯的,我只是不明白。解決循環引用(C#)

這裏是我的項目:

Flip.Main  (ASP.NET MVC) 
Flip.Domain (C# DLL) 
Flip.Services (C# DLL) 
Flip.Utility (C# DLL) 

基準電流/依賴性:

Flip.Main ->  Flip.Domain, Flip.Services, Flip.Utility 
Flip.Services -> Flip.Domain, Flip.Utility 
Flip.Domain -> Flip.Utility 

我要組織我的項目,我的服務項目有所有服務的方式,我的領域的項目模型,資料庫和'流利'擴展來查詢模型,主要和實用工程幾乎是自我解釋。遇到

問題:

1)我有我的Flip.Services項目,該項目需要派出本地化電子郵件的EmailService。所有本地化都在Flip.Main的App_GlobalResources中完成。不知道如何將強類型電子郵件和其他本地化資源現在加入到我的服務層,因爲Flip.Main已經取決於服務層,因此我可以依賴於主項目。

2)我有業務類,例如CustomerSearchFilter表示一個強類型的搜索查詢。我希望Flip.Domain項目之外的業務類,因爲它們不屬於域模型的一部分。然而,在我的CustomerSearchFilter類中,我有域類實例(例如CustomerGroup),因此它需要知道域類。同時,我的Flip.Domain項目中的Fluent界面需要知道CustomerSearchFilter是什麼,所以我可以將它應用到我的IQueryable接口。再循環參考。

3)我有一個自定義[AuthorizeSessionState]屬性,我用我的ASP.NET MVC Flip.Main項目來裝飾特定的控制器動作。這是一個ActionFilterAttribute,它需要實例化駐留在我的Flip.Services項目中的SessionService。我不能把它放到我的Utility類中(因爲Flip.Services已經引用了Flip.Utility)。我不認爲他們應該在Flip.Main - 我必須爲此做另一個項目!?

(20以上)

我覺得我犯了一個錯誤的地方的路線,尤其是當我看到別人通常不會遇到循環引用的問題。幫幫我?

回答

5

使用所有非平凡類的接口。將接口放置在與實現不同的組件中。

+2

這就是我要爲第2項提出的建議。如果您覺得兩個兄弟組件需要知道對方的類,只需分開一個接口並讓它們都使用它們即可。 – 2009-08-24 06:36:59

+0

您可以考慮的一件事是使用基本類型與虛擬成員而不是接口。通過這種方式,您可以爲主機應用程序提供功能性的默認實現,這可以使測試變得更簡單,並與實現共享一些邏輯。 – mcintyre321 2013-06-27 10:41:26

0

問題歸結到你的命名空間,您可以通過DLL分開單獨什麼什麼。如果你有一個很好的理由來保持一切的模塊化,你必須努力工作。但是,如果這些DLL中的每一個都只有一個或兩個類,那麼也許你可以將它們合併在一起?

+0

該DLL相當大。我在Flip.Services DLL中有12種不同的服務(可能會增長到> 20)我的Flip.Domain DLL中的模型,模型部分類擴展,存儲庫類和流暢的擴展方法,Flip.Utility中的加密和業務支持類以及Flip.Main中的網站。對我來說似乎合乎邏輯? – Alex 2009-08-24 05:13:33

+0

那麼命名空間是。如果您希望在不使用整個程序的情況下更新它們,並重新使用代碼,則可以使用程序集。但正如我所說,如果你只有一個應用程序或一小組共享功能,那麼把所有東西放在一起。 – Spence 2009-08-25 00:34:49

0

花幾分鐘的時間,整理程序...爲每個項目創建一個標識符(FM,FS,FD,FU)。頁面上列出的每個公開訪問的過程,然後添加一個標識爲一個項目,如果該項目使用的過程...

然後你就可以看到哪些程序需要在(或訪問)的項目。

希望有幫助!

+0

正如我在上面寫的那樣,問題在於2個項目經常需要互相瞭解。你的方法如何解決它? – Alex 2009-08-24 05:30:23

+0

如果你嘗試這個建議,你會看到(除其他外,我敢肯定)你的一些過程並不是最適合的項目......例如在main和not util中進行本地化似乎並不正確。根據您之後的模塊化級別,您可能會發現語言管理完全適合自己。 – 2009-08-24 06:21:16

0
  1. 您可以將您的本地化電子郵件字符串置於Flip.Services中。缺點是你有兩個地方來維護本地化資源。你也可以爲你的所有資源設置一個單獨的dll來最小化編輯資源的地方。
  2. 您必須將流暢接口移動到其他dll或使CustomerSearchFilter成爲域的一部分。
  3. 您將需要添加更多項目或重新排列結構並使用命名空間來創建分隔。
+0

將使得CustomerSearchFilter(和其他沒有數據表示的業務對象)成爲該域的一部分嗎? – Alex 2009-08-24 05:48:38

0

這聽起來像你的具體實現而不是接口/合同的建設。正如Ima建議定義界面來描述某個類應該能夠做什麼。當你聲明屬性,參數等時使用這個接口。保持接口與實現分離,實現和使用接口的項目都可以引用接口項目。

然後,您可以得到使用依賴注入使代碼更容易測試作爲一個側

+0

你有這樣的項目結構的例子文章或類似嗎?這是常見的嗎? – Alex 2009-08-24 05:47:37

0

在域的「層次」的不錯的選擇,存儲庫和服務住在同一個邏輯層次,域上方在基礎設施角色。我建議將你的資源庫實現(查詢等)移到域本身之外。至少解決了#2。

+0

那會是什麼樣的項目? (技術術語?) – Alex 2009-08-24 06:34:41