動態屬性簡介 (Visual Studio)
更新:2007 年 11 月
注意事項: |
---|
自 Visual Studio 2005 起,已將動態屬性 (Dynamic Property) 的使用者介面移除,但是仍然支援動態屬性。如果從舊版的 Visual Studio 中匯入專案,動態屬性設定都會保留在程式碼中,在執行階段仍然可以使用。不過,我們建議您改用 [專案設計工具] 來指定應用程式設定。如需詳細資訊,請參閱專案設計工具、設定頁和管理應用程式設定。 |
動態屬性允許您設定您的應用程式,讓其中一些或全部的屬性值可儲存在外部組態檔中,而非應用程式的編譯程式碼中。藉由提供系統管理員各種方法來更新可能需要隨時間變更的屬性值,這能夠降低部署應用程式後維護此應用程式所需的總成本。例如,假設您正在建置 (Build) 的應用程式在開發過程期間使用的測試資料庫,而您需要在部署時將它轉換成實際執行資料庫。如果您將屬性值儲存在應用程式內部,您就必須在部署之前手動變更所有資料庫設定,接著重新編譯原始程式碼。如果您將這些值儲存在外部,您只要在外部檔案中進行一次變更,應用程式就會在下次執行時取得新值。
安全性注意事項: |
---|
儲存在組態檔中的屬性值並不安全。機密資料,如密碼和信用卡資訊,不應該以動態屬性的方式儲存。 |
您可以在任何編譯為 .exe 檔案的應用程式中使用動態屬性。編譯 DLL 的專案無法直接使用動態屬性,但是 DLL 屬性可由參考 .dll 的 .exe 以動態方式設定。雖然這些應用程式中任何元件、表單或控制項的屬性都能夠以動態方式處理,但其中一些屬性比其他屬性更適合成為動態屬性。您經常會儲存及擷取的屬性是連接到可能變更的外部資源,包括資料庫、事件記錄檔或效能計數器。這些屬性有許多可視為動態屬性的預設候選者。
注意事項: |
---|
這個主題中的範例程式碼必須依賴 SqlConnection 物件和組態檔的存在;如果這些並不存在,就會導致編譯錯誤。 |
動態屬性和組態檔
當您將屬性設定為可組態的,它的值就會寫入組態檔,而類別 (Class) 中會插入程式碼來指示應從這個外部資源來擷取屬性值。組態檔隨著應用程式的類型而不同;Web 應用程式使用 Web.config 檔案,而 Windows 開發的應用程式則使用具有 .config 副檔名的類似檔案,應用程式中所有的表單及元件都使用單一的組態檔。您無法切換至不同的組態檔或是在單一應用程式中使用多個檔案。
在組態檔中,屬性是透過 XML 保存 (Persist)。例如,假設您之前指示資料連接的 ConnectionString 屬性應該儲存在組態檔中。您將會在程式碼編輯器中看到以下程式碼,指出要將值儲存在外部:
Me.SqlConnection1.ConnectionString = _
System.Configuration.ConfigurationManager. _
AppSettings.Get("SqlConnection1.ConnectionString")
this.sqlConnection1.ConnectionString =
System.Configuration.ConfigurationManager.
AppSettings.Get("SqlConnection1.ConnectionString");
安全性注意事項: |
---|
如需關於建立安全資料連接的詳細資訊,請參閱保護連接資訊 (ADO.NET)。 |
在組態檔中,這個屬性的值會透過 XML 來儲存,方式是使用表單的程式碼中所指示的機碼:
<configuration>
<appSettings>
<add key="sqlConnection1.ConnectionString" value="data source=myserver;initial catalog=Apps;Integrated Security=SSPI;packet size=4096" />
</appSettings>
</configuration>
組態檔中的每個值都會被指派機碼 (Key),可用來儲存及擷取這個值。機碼的初始部分是表示值的來源元件。例如,以下這兩個機碼表示單一應用程式中兩個不同資料連接上的 ConnectionString 屬性:
<configuration>
<appSettings>
<add key="sqlConnection1.ConnectionString" value="data source=myserver;initial catalog=Apps;Integrated Security=SSPI;packet size=4096" />
<add key="sqlConnection2.ConnectionString" value="data source=myserver;initial catalog=Apps;Integrated Security=SSPI;packet size=4096" />
</appSettings>
</configuration>
您可以直接修改組態檔,以便能夠動態更新您應用程式中的屬性值。下次應用程式啟動時,它就會更新這些值。
就某種程度而言,組態檔與資源檔類似;兩者都是用來將值儲存在編譯應用程式的外部,且兩者都使用 XML 來儲存資訊。但資源檔的用途與組態檔卻相當不同。資源檔是用來儲存字串及其他可當地語系化的資源以作翻譯之用,而組態檔 (就動態屬性而言) 則是用來更新屬性值。資源檔中的值是準備翻譯之用但通常不會變更,而組態檔中的動態屬性值可視需要變更。此外,您也可以將多個資源檔與一專案產生關聯,但您的應用程式只能有一個組態檔。如需資源檔的詳細資訊,請參閱階層式組織當地語系化的資源。
將多個屬性設定為相同機碼
多個屬性可參考組態檔中相同的機碼值配對。例如,如果您的類別中有三個都存取相同資料庫的元件,您可以將這三個元件的 ConnectionString 屬性儲存在相同的機碼值配對當中。這表示如果資料庫變更,您可以更新設定檔中的單一值來將變更套用至所有這三個元件。若要這麼做,您可以將每個屬性設定為相同的機碼,如以下所示:
Me.SqlConnection1.ConnectionString = _
System.Configuration.ConfigurationManager. _
AppSettings.Get("SqlConnection1.ConnectionString")
Me.SqlConnection2.ConnectionString = _
System.Configuration.ConfigurationManager. _
AppSettings.Get("SqlConnection1.ConnectionString")
Me.SqlConnection3.ConnectionString = _
System.Configuration.ConfigurationManager. _
AppSettings.Get("SqlConnection1.ConnectionString")
this.sqlConnection1.ConnectionString =
System.Configuration.ConfigurationManager.
AppSettings.Get("SqlConnection1.ConnectionString");
this.sqlConnection2.ConnectionString =
System.Configuration.ConfigurationManager.
AppSettings.Get("SqlConnection1.ConnectionString");
this.sqlConnection3.ConnectionString =
System.Configuration.ConfigurationManager.
AppSettings.Get("SqlConnection1.ConnectionString");
請注意,雖然使用的元件不同,但這些元件都參考 sqlConnection1.ConnectionString 的機碼。
當您為多個屬性選擇相同的機碼時,組態檔中只會建立一個項目。儲存的初始值是來自於取得機碼的第一個屬性。
資料型別和動態屬性
XML 會將任何項目儲存為字串。如果儲存的屬性值不是字串,就會在程式碼編輯器中看到指出屬性值的資料型別的其他資訊。例如,假設您正在以動態方式儲存 Timer 元件的 Interval 和 Enabled 屬性值。在組態檔中,這個屬性會儲存如下:
<appSettings>
<add key=timer1.Interval" value="100" />
<add key=timer1.Enabled" value="True" />
</appSettings>
在程式碼編輯器中,您會看到這段程式碼指出擷取的值需要變更為 Double 資料型別 (Visual Basic):
Me.Timer1.Enabled = (New System.Configuration. _
AppSettingsReader()).GetValue("timer1.Enabled", GetType(Boolean))
Me.Timer1.Interval = (New System.Configuration. _
AppSettingsReader()).GetValue("Timer1.Interval", GetType(Double))
this.timer1.Enabled = (bool)(new System.Configuration.
AppSettingsReader().GetValue("timer1.Enabled", typeof(bool)));
this.timer1.Interval = (System.Double)(new System.Configuration.
AppSettingsReader().GetValue("timer1.Interval", typeof(System.Double)));
注意事項: |
---|
共有兩個計時器,一個是針對 Windows Form,另一個是針對伺服器架構的應用程式,兩者在程式設計模型上稍有不同。這個範例使用伺服器架構的計時器。如需這兩種可供使用的計時器的詳細資訊,請參閱伺服器端計時器簡介。 |
動態屬性的效能及安全性考量
當使用動態屬性時,您可能要注意兩個項目。首先,動態屬性儲存和擷取可能會多少影響您應用程式的效能。從已編譯的應用程式中擷取屬性值,要比從組態檔中擷取屬性值來得稍快。當應用程式第一次存取組態檔值時,效能會因應用程式讀取檔案而稍受影響。但這影響並不嚴重,而且也不會被察覺。後續擷取這個值或其他屬性對效能的影響會小得多,這就類似從雜湊表讀取值。
其次,如果您要將使用者 ID 和密碼等屬性值儲存至外部檔案,就必須要控制誰能夠存取該檔案及檔案中的值。達成此目的的方法之一是利用 Windows 存取控制清單 (ACL) 設定檔案的安全性。存取控制清單會指定不同使用者在特定檔案及目錄上可執行的作業。除此之外,如果您使用 Web 應用程式,您可以利用 Windows、網際網路資訊服務 (IIS) 及 SQL Server 所提供的整體安全性選項。在這個模型中,使用者的區域網路驗證 (Authentication) 認證也會用來存取資料庫資源,且在連接字串中不會使用明確的使用者名稱或密碼。
如需安全性的詳細資訊,請參閱 Windows 文件或下列各頁: