Introduction to Dynamic Properties
Dynamic properties allow you to configure your application so that some or all of its property values are stored in an external configuration file rather than in the application's compiled code. By providing administrators with the means to update property values that may need to change over time, this can reduce the total cost of maintaining an application after the application has been deployed. For example, suppose you are building an application that uses a test database during the development process, and you need to switch it to a production database when you deploy it. If you store the property values inside the application, you have to manually change all of the database settings before you deploy, and then recompile the source code. If you store these values externally, you can make a single change in the external file and the application will pick up the new values the next time it runs.
Security Note Property values stored in a configuration file are not secure. Sensitive data such as passwords and credit-card information should not be stored as dynamic properties.
You can use dynamic properties in any application that compiles to an .exe file. Projects that compile a DLL cannot use dynamic properties directly, however DLL properties can be set dynamically by the .exe referencing the .dll. Although the properties of any component, form, or control in these applications can be handled dynamically, some properties make better dynamic property candidates than others. Most often, you will store and retrieve properties that connect to external resources that might change, including databases, event logs, or performance counters. Many of these properties are identified as default candidates for dynamic properties. For more information, see "Default Dynamic Properties" below.
Note The example code in this topic relies on the existence of a SqlConnection object and a configuration file; it will cause compilation errors without them. For more information on creating a SqlConnection object, see Walkthrough: Simple Data Access in a Windows Form. For more information on creating a configuration file, see Walkthrough: Storing and Retrieving Dynamic Properties.
Dynamic Properties and Configuration Files
When you set a property as configurable, its value is written to a configuration file and code is inserted in the class to indicate that the property value should be retrieved from this external resource. The configuration file varies based on the type of application; Web-based applications use the Web.config file, and Windows-based applications use a similar file with the extension .config. All of the forms and components in an application use a single configuration file. You cannot switch to a different configuration file or use multiple files within a single application.
Within the configuration file, properties are persisted via XML. For example, suppose you indicated that the ConnectionString property for a data connection should be stored in the configuration file. You would see this code in the Code Editor indicating that the value is stored externally:
' Visual Basic Me.SqlConnection1.ConnectionString = CType(System.Configuration.ConfigurationSettings.AppSettings.GetValues("SqlConnection1.ConnectionString") // C# this.sqlConnection1.ConnectionString = ((string)( System.Configuration.ConfigurationSettings.AppSettings.GetValues("SqlConnection1.ConnectionString"))));
Security Note For more information about creating secure data connections, see Database Security.
In the configuration file, the value for this property would be stored via XML, using the key indicated in the form's code:
<configuration> <appSettings> <add key="sqlConnection1.ConnectionString" value="data source=myserver;initial catalog=Apps;Integrated Security=SSPI;packet size=4096" /> </appSettings> </configuration>
Each value in the configuration file is assigned a key that is used to store and retrieve the value. The initial portion of the key indicates the component from which the value originated. For example, these two keys indicate a ConnectionString property on two different data connections within a single application:
<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>
You can modify the configuration file directly in order to dynamically update the property values in your application. The next time the application starts, it will update the values.
In a sense, configuration files are similar to resource files; both are used to store values outside the compiled application and both use XML to store their information. However, resource files serve a much different purpose than configuration files. Resource files are used to store strings and other localizable resources for translation purposes, while configuration files (in the case of dynamic properties) are used to update property values. The values in a resource file are meant to be translated but typically not changed, while the dynamic property values in a configuration file can be changed as needed. Also, you can associate multiple resource files with a project, but you can only have a single configuration file for your application. For more information on resource files, see Hierarchical Organization of Resources for Localization.
Setting Multiple Properties to the Same Key
Multiple properties can reference the same key-value pair in a configuration file. For example, if you have three components in your class that all access the same database, you can store the ConnectionString property for each in the same key-value pair. This means that if the database changes, you can update a single value in the settings file to apply the change to all three components. You would do this by setting each of the properties to the same key, like this:
' Visual Basic Me.SqlConnection1.ConnectionString = CType(System.Configuration.ConfigurationSettings.AppSettings.GetValues("SqlConnection1.ConnectionString") Me.SqlConnection2.ConnectionString = CType(System.Configuration.ConfigurationSettings.AppSettings.GetValues("SqlConnection1.ConnectionString") Me.SqlConnection3.ConnectionString = CType(System.Configuration.ConfigurationSettings.AppSettings.GetValues("SqlConnection1.ConnectionString") // C# this.sqlConnection1.ConnectionString = ((string)(configurationAppSettings.GetValue System.Configuration.ConfigurationSettings.AppSettings.GetValues("SqlConnection1.ConnectionString")))); this.sqlConnection2.ConnectionString = ((string)(configurationAppSettings.GetValue System.Configuration.ConfigurationSettings.AppSettings.GetValues("SqlConnection1.ConnectionString")))); this.sqlConnection3.ConnectionString = ((string)(configurationAppSettings.GetValue System.Configuration.ConfigurationSettings.AppSettings.GetValues("SqlConnection1.ConnectionString"))));
Note that while the components in use differ, they all refer to the key for sqlConnection1.ConnectionString.
When you choose the same key for multiple properties, only one entry is made in the configuration file. The initial value stored is that from the first property that was given that key.
Data Types and Dynamic Properties
XML stores everything as a string. If the property value you are storing is not a string, you will see additional information in the Code Editor to indicate the data type for the property value. For example, suppose you are dynamically storing the value for a Timer component's Interval and Enabled properties. In the configuration file, this property would be stored like this:
<appSettings> <add key=timer1.Interval" value="100" /> <add key=timer1.Enabled" value="True" /> </appSettings>
In the Code Editor, you would see this code to indicate that the retrieved value needs to be changed to a Double data type:
' Visual Basic Me.Timer1.Enabled = System.Configuration.ConfigurationSettings.AppSettings.GetValues ("Timer1.Enabled") Me.Timer1.Interval = System.Configuration.ConfigurationSettings.AppSettings.GetValues ("Timer1.Interval") // C# this.timer1.Enabled = ((bool)(configurationAppSettings.GetValue("timer1.Enabled", typeof(bool)))); this.timer1.Interval = ((System.Double)(configurationAppSettings.GetValue("timer1.Interval", typeof(System.Double))));
Note There are two timers, one for Windows Forms and one for server-based applications, with slight differences in programming models. This example uses the server-based timer. For more information on the two timers available, see Introduction to Server-Based Timers.
Default Dynamic Properties
By default, the DynamicProperties node of the Properties window lists component properties that are likely to be stored in an external file. The following figure shows the way the Properties window arranges these items:
Dynamic Properties in the Properties Window
If you want to dynamically store a value for a property that is not listed in the Properties window, you can do so by selecting the ellipsis next to the Advanced listing in this section of the Properties window. This opens the Dynamic Properties dialog box, which lists all of the properties with an elementary data type (such as Boolean, string, float, double, integer, short, and so on) for the current component or form.
Note that if no properties are listed in the DynamicProperties node of the Properties window, this means that there are no properties that are configurable by default for that component. However, you can still add properties using the dialog box.
Performance and Security Concerns with Dynamic Properties
There are two items that may be of concern when you use dynamic properties. First, dynamic property storage and retrieval may affect your application's performance somewhat. Retrieving property values from within the compiled application is slightly faster than retrieving properties values from the configuration file. The first time a configuration file value is accessed by the application, there will be a slight performance impact as the application reads the file. This impact is very minor, however, and should not be noticeable. Any subsequent retrieval of that or other properties has a much smaller performance impact — similar to reading a value from a hash table.
Second, if you are storing property values such as user IDs and passwords to an external file, you will want to control who has access to the file and the values it contains. One way to accomplish this is to secure your file with a Windows access control list (ACL). An access control list specifies what operations different users can perform on specific files and directories. In addition, if you are working with a Web-based application, you can take advantage of the integrated security option provided by Windows, Internet Information Services (IIS), and SQL Server. In that model, a user's authentication credentials for the local network are also used to access database resources, and no explicit user name or password are used in the connection string.
For details about security, see your Windows documentation or the following topics:
- Best Practices for Securability
- .NET Framework Security
- Securing ASP.NET Web Applications
- Introduction to ADO.NET Connection Design Tools
Walkthrough: Storing and Retrieving Dynamic Properties | Configuring Applications Using Dynamic Properties | Setting Dynamic Properties | Removing Keys from Properties | Changing the Value of Dynamic Properties