2014-04-29 55 views
5

我正在開發MVC應用程序。 我在我的應用程序中有兩個項目。 一個是MVC應用程序包含,Controller和Views,第二個是DataLayer項目。在哪裏寫連接字符串?在app.config或web.config?

我對寫入連接字符串的位置感到困惑,因爲在發佈應用程序時,它需要web.config文件,我從DataLayer項目獲取數據,因此應該在app.config/Web中添加連接字符串。數據層項目的配置?

另外,想知道app.config和web.config的用途和區別是什麼?

回答

6

每個項目都帶有一個配置文件在創建時的Web.config。一個普通的類庫有一個叫做app.config的通用類庫。 Web項目更具體,因此其文件名爲web.config,並附帶特定於Web的參數。他們都服務於相同的目的。

您面臨的問題是,默認情況下只會部署可執行項目的配置文件(web.config)。您有幾個選項:

  1. 將您的連接字符串添加到web.config並將其傳遞到您的數據層。這很簡單(最常見),但將配置信息從數據層項目中分離出來。
  2. 讓您的數據層使用System.Configuration.ConfigurationManager讀取web.config。這可以減少將數據傳遞到數據層,但會創建強大的依賴關係(如果沒有格式正確的web.config文件,數據層將無法工作)。
  3. 將app.config部署爲XML內容並編寫自定義代碼,以便您的數據層可以讀取它。這是更多的工作,但它將您的數據配置從Web配置中取出。
  4. 稍微改變#2,您可以在web.config中創建名爲「dataLayer」的custom config section。這可以通過System.Configuration.ConfigurationManager閱讀。我更喜歡這種方法,因爲它似乎是一個很好的平衡。你在「默認」配置文件中有一個自定義的強類型配置部分。

這個related question也有一些很好的信息。

+0

我已添加參考。 MVC項目中的數據層,如何將它傳遞給數據層? – bnil

+0

[這是如何](http://stackoverflow.com/questions/6134359/read-connection-string-from-web-config)你從web.config中讀取它。然後將它作爲字符串傳遞給數據層中的方法或構造函數。 – nunzabar

3

連接字符串進入Web.config。默認情況下,它將查找執行程序集的配置並忽略引用程序集的配置文件。

引用程序集的配置文件可能在設計時使用。例如,如果您在數據層程序集中使用實體框架,它將在app.config中存儲用於從數據庫構建模型的連接信息。

當我到達Web項目將要運行並通過數據層訪問數據的時候,我通常只是將該連接信息複製到web.config中。

+0

DataLayer將使用來自web.config文件的連接字符串? – bnil

+2

提示:如果你不在設計時使用它(例如使用EF Code-First),你甚至可以將它從app.config中刪除,並將其保留在網站項目的web.config中 –

3
  • Web.Config用於asp.net web項目/ web服務。
  • App.Config用於Windows窗體,Windows服務,控制檯 應用程序和WPF應用程序。

添加您的連接字符串中數據層項目

+0

ok,所以我會在Datalayer的WebConfig文件中添加連接字符串。但是發佈應用程序呢?它需要MVC項目的web配置而不是dataLayer項目... – bnil

+2

類庫中沒有web.config。 – nunzabar

1

我會先回答你的問題,然後繼續討論什麼是IMO更重要的考慮因素。對於這個特定的用例,我更喜歡DI模式,在這種模式中,消費者告訴提供者連接字符串是什麼。這使得你的數據層不知道數據庫,並允許它與滿足它的合同的任何數據存儲進行通信。總之,由於您的MVC項目是數據層的使用者,因此連接字符串存儲在web.config中。 BUT IT IS STORED ENCRYPTED!!!

現在,在這裏實際上存在比物理地寫連接字符串更深的問題,那就是在消費代碼和配置存儲之間建立一個抽象。如果你這樣做,你存儲配置值的地方就變得基本上不相關。

我總是在每個圖層(項目)內創建一個配置類,以提供該圖層內消耗的配置值。這提供了幾個好處:

  1. 它允許在使用強類型值時。如果你的配置值是一個int,你會得到一個int,並且當你使用它時不需要轉換它。
  2. 它允許可能已被無意中排除在配置文件之外的默認值。這使得你的代碼更加健壯。
  3. 它可以靈活地存儲值的存儲位置。您可以將一些值放入配置文件中,其他值放入數據庫中,還可以從遠程Web服務中獲取更多值。如果你決定改變一家商店,你只需要在一個地方編輯代碼 - 並不是每個地方的價值都被消耗掉了。
  4. 隨着解決方案的增長和項目的添加,模式可以很好地擴展並保持配置的隔離。
  5. 它從您的代碼中刪除魔術字符串。

取而代之的是以下的,其中有一個討厭的魔法字符串:

return System.Configuration.ConfigurationManager.AppSettings["DefaultUserName"]; 

你會寫

MyApp.Configuration.DefaultUserName 

這是一個非常基本的實現,它返回一個強類型的例子(在這種情況下,DayOfWeek)。它有一個幫助你的方法來幫助你從商店中抽取行爲。如果您需要包含多個商店,則此方法將採用類型T的泛型,其中T是商店的類型。在下面的簡化示例中,它只是從配置文件中提取:

public class Configuration 
    { 
     private const DayOfWeek FailsafeDefaultDayOfWeek = DayOfWeek.Saturday; 

     /// <summary> 
     /// A default for the day of week 
     /// </summary> 
     public static DayOfWeek DefaultDayOfWeek 
     { 
      get 
      { 
       string dayOfWeekString = GetSettingValue("DefaultDayOfWeek"); 

       try 
       { 
        return (DayOfWeek)Enum.Parse(typeof(DayOfWeek), dayOfWeekString); 
       } 
       catch (Exception) 
       { 
        // If someone screws up and forgets to include a value, or the value cannot be cast: 
        return FailsafeDefaultDayOfWeek; 
       } 
      } 
     } 

     /// <summary> 
     /// Helper method to easily pull a value from a configuration store. 
     /// </summary> 
     /// <param name="settingName"></param> 
     /// <returns></returns> 
     private static string GetSettingValue(string settingName) 
     { 
      try 
      { 
       return System.Configuration.ConfigurationManager.AppSettings[settingName]; 
      } 
      catch (Exception) 
      { 
       throw new MissingConfigurationValueException(settingName); 
      } 
     } 
    } 
相關問題