2011-08-11 16 views
0

我們有一個很常見的架構方法:你在哪裏放了常見的web URI路徑

數據庫

庫層

Business Objects公司

服務層 - 服務DTO的給客戶

Web層(MVC)

我們有很多通向資源的途徑,尤其是圖片和播客(Ex。 http://media.mysite.com/podcasts/)。我想創建一個靜態實用類屬性:

MySite.Utils.ImagePathUri

MySite.Utils.PodcastsPathUri

我的問題是:你在哪裏把URI路徑?這個實用程序類去哪個項目?

最初,它似乎是一個無可挑剔的:網絡層。這是一個網站。我應該能夠改變一個網站的網址,而其他層不知道它。

一切都很好,但是。 。 。那麼有一天我的一項服務需要提供SyndicationFeed類型。 SyndicationFeed需要一個完整的URI,而不僅僅是一個部分文件名。但是這些服務不應該有權訪問完整路徑。或者他們應該?

我與自己辯論幾件事情,但不能拿出一個堅定的立場:

  1. 移動的路徑的服務層。這將Web層緊密地耦合到服務層,但也許沒關係,因爲它們緊密結合在一起。
  2. 將路徑移至業務對象或回購站。我不喜歡這樣,但如果我願意把它放到服務層,我至少要考慮它。
  3. 請勿在服務圖層中使用SyndicationFeed,而只能在Web圖層中使用它。解決了這個問題,但似乎SyndicationFeed應該屬於服務層。
  4. 放棄SyndicationFeed。任何SyndicationFeed都可以在MVC中使用PartialView更容易地創建,該PartialView可以生成適當的XML,而不必混淆像ElementExtensions這樣的膨脹抽象。我喜歡這個,但是我們在很多地方都使用了SyndicationFeed,所以我們會做最多的解釋。
  5. 向服務層的聯合提要中提供一個假uri,然後在Web層中對其進行更改。你能說黑客嗎?
  6. 將完整路徑放在數據庫中。一開始聽起來不錯,但後來我意識到,只要有動態生成的圖像,它就會中斷。
  7. 一些其他的解決方案,不會出現在我身上。

您的想法是什麼?你在哪裏把網頁資源的實用程序類(圖像,播客等)?如果你說「web層」,你對SyndicationFeed問題有什麼看法?

UPDATE

在一天結束的時候,我決定放棄了SyndicationFeed類,它否定了需要包括路徑在服務和存儲庫層的文件。然而,問題仍然出現在其他地方並使用DI,特別是像Ninject這樣的IoC是非常有意義的。因此,將這些包裝到一個共同的界面中。

SyndicationFeed,查看發動機及爲什麼不聲明陳述更好

我拋棄了SyndicationFeed,而是創造了我需要使用剃刀的XML。不僅更容易創建,而且它的可讀性高出1000%。我認爲使用命令式代碼(C#,VB等)來創建XML只是比它應該的更難。 XML是聲明式的,不是必需的。相反,我現在已經決定視圖引擎(例如Razor)的聲明性語法比命令式語言更易於使用。

回答

1

我感到你的痛苦。我也有類似的情況,我通過將uri從我的web層傳遞給我的存儲庫層來解決。

我的項目使用Ninject進行綁定,並且由於我已經將連接字符串傳遞給Ninject存儲庫,所以傳遞我的路徑字符串也很簡單。

我的存儲庫然後按摩路徑字符串並在我的業務對象中填充必要的屬性。

這是正確的嗎?我不知道,但它現在起作用。我對解決方案並不滿意,但我還沒有機會嘗試改進。

想聽聽其他人如何處理這件事。

+0

當你說「將uri傳遞給存儲庫層」時,你的意思是通過配置文件(例如web.config)中的設置還是引用該項目? – John

+0

我的路徑字符串位於web.config文件中。 Ninject的綁定允許傳遞參數。 '綁定(的RepositoryInterface)()。(的RepositoryClass).WithConstructorArgument(「connectionString」,connString)。WithConstructorArgument(「path」,uri)' 無可否認,我的解決方案依賴於Ninject來爲我完成重任。 – OverForkOver

1

面對類似的情況,我覺得最好的方法是定義一個配置界面,導致一個對象在最頂層。在之間的每個層將改進的界面與更具體的屬性和操作:

public interface IWebConfiguration 
{ 
    string RootImageUri { get; } 
} 

服務將層將自行添加需要的東西:

public interface IServicesConfiguration 
{ 
    string SyndicationFeedUri { get; } 
} 

public interface IDatabaseConfiguration 
{ 
    string ConnectionString { get; } 
} 

最後,我不得不在網絡層實現連接所有接口的特定對象。醜陋?也許。我會承認有電話isa在那裏和一些鑄造。

但是,我能夠然後傳遞給每個層強類型的接口。在我看來,它比從一個配置文件中獲取普通舊字符串的一系列調用要好。另外,因爲每個屬性都是特定於某個圖層的,並且聚集對象正在被傳遞,所以我只需要加載一次配置。