2016-05-12 69 views
2

我有一個接口IApplicationConfig,基本上保持類似於數據庫,Blob存儲和其他東西的ConnectionStrings。對於我的解決方案中的每個「可執行」項目,比如網站,命令行工具等,都有一個接口的具體實現,該接口被配置爲通過依賴注入來解析。放在哪裏的ConnectionStrings洋蔥建築

我的問題是,我應該在哪裏把這些IApplicationConfig -Implementations?

在我的每個「可執行」項目中,我的web.config/app.config旁邊? 或在基礎設施,如Project1Config.cs,Project2Config.cs等?

+3

由於其組成根設置儘可能靠近根,所以可以在'App_Start'或者'web.config'旁邊。 – janhartmann

回答

4

前言

我已經實現管理配置中的一個方式我遵循洋蔥結構規則構建的應用程序如下。

在我考慮的管理配置(例如日誌記錄以及)作爲基礎設施的關注這種特殊情況下,這樣就意味着這顯然不是我的應用程序核心的一部分。這是因爲它是另一層。

哲學當然

爲了證明基礎設施的關注請看看下面的圖:

Onion Architecture diagram

*圖像從Shawn J Lee的博客鏈接。

在這裏您可以看到日誌記錄發生在基礎架構片或層中,我曾指出管理配置也是基礎結構問題。

現在,如果您的體系結構中的任何地方需要掌握配置管理器的實現,只需在構造函數中請求您的IApplicationConfig,並根據您最喜歡的DI container/framework中的配置獲得正確的實現注入。這被稱爲Hollywood Principle或更好的控制反轉。

夠bab呀,你說呢?現在,讓我們直接到科技示範...

執行總覽

你問哪裏把實際的實現。我將構建這些位作爲:

  • 應用芯層(一個或多個)
    • 域接口組件
  • 基礎設施層
    • 配置組件
    • 依賴解析組件
  • UI層
    • 命令行組裝
    • 網站裝配

獲取困吧?現在轉向更高的齒輪。

實現例如

我會嘗試在這裏說明短期實際執行的細節。

域接口組件

這是你把所有這些應用程序核心-and其它層如公將開始處理或利用界面處的層。

說我們有IApplicationConfig.cs

public interface IApplicationConfig 
{ 
    ConnectionStringSettingsCollection GetConnectionStrings(); 
} 

配置裝配

在這裏,你可以有你IApplicationConfig接口的實際執行(一個或多個)的地方。把它作爲一個單獨的程序集是有問題的,但它實際上只是一個實現細節,我個人將所有配置管理實現存儲在這裏。

。例如IApplicationConfig的實現可以像ApplicationConfig.cs

public class ApplicationConfig : IApplicationConfig 
{ 
    public ConnectionStringSettingsCollection GetConnectionStrings() 
    { 
     return ConfigurationManager.ConnectionStrings; 
    } 
} 

解決依賴裝配

這是你「鏈接」你有需要的實現接口。在這裏我使用Ninject並創建了一個Ninject module它調用它作爲ConfigModule,一個簡單的例子:

public class ConfigModule : NinjectModule 
{ 
    Bind<IApplicationConfig>().To<ApplicationConfig>(); 
} 

最後的命令行/網站裝配

通常這些的Composition Root或入口點您構建對象圖的應用程序。話雖如此,我們現在只需要加載我們Ninject模塊:

private static IKernel CreateKernel() 
{ 
    var kernel = new StandardKernel(); 

    var modules = new List<INinjectModule> 
     { 
      new ConfigModule(), 
      new WhateverModule(), 
      ... 
     }; 

    kernel.Load(modules); 
} 

引用你需要添加命令行/網站裝配

具有接口契約,它的實現分離,在這裏你只需要添加對的:

  • 依賴解析組件
  • 域接口組件

現在你可以在你想要的任何層使用你的實現。

後記

這個例子已經從我的實際應用考慮,如果你與事物命名不同意,我同意......這是not an easy thing做。

+0

這正是我如何做到的。所以你基本上說這是一個實現細節在哪裏把配置 – Sandro

+0

@Sandro是的,我認爲這是確切的。 – kayess

+0

@Sandro你有沒有成功完成這項任務? – kayess

0

我想使界面更加具體,以便它指定什麼是需要一個特定的類,或爲組裝,而不是應用程序。如果您的數據訪問位於其自己的程序集中,那麼ISettings應該特定於該程序集,而不是與主機應用程序共享。然後我也會將實現放在需要它的程序集中。主機應用程序不應該「知道」另一個程序集使用的接口,也不應該負責創建或提供實現。

如果實施將會從App.config中/ web.config中讀取,然後我會確保它會拋出異常詳細,如果這些設置丟失。這樣,依賴於該程序集的人不必猜測需要什麼設置。

用於數據訪問組件應駐留在任一數據訪問組件或在另一組件的共DI構造。主機應用程序不應該「非常瞭解」其他程序集,因爲它包含了這些程序集的詳細註冊信息。主機應用程序只調用一些外部安裝程序來註冊該程序集的依賴關係。

將自己的DI配置放置在自己的程序集中也是有意義的。 (使用Windsor的示例here)。這樣,數據訪問程序集就構建用於依賴注入,但不依賴於任何一個DI容器。如果有必要,你可以創建一個溫莎安裝程序,一個Autofac安裝程序,需要等(根據您的環境或預期的使用,可能是矯枉過正。)

+0

我已經擁有一個自己的程序集,可以用模塊中組織的DI組態進行依賴關係解析。數據訪問在基礎架構中,但這是否意味着檢索其ConnectionString應該位於同一個程序集中? – Sandro

+0

理想情況下,無論組件需要配置數據,這都是接口和實現應該在哪裏。這種方式是自成體系的。 –

+0

不應該接口都進入核心? – Sandro