Developer .NET UPDATE, February 25, 2003
The common ways to store an application's custom configuration settings include using the Windows .NET Framework's .config files. Here’s how you can retrieve an application’s configuration settings and dynamically detect changes in those settings.
February 24, 2003
Developer .NET UPDATE—brought to you by the Windows & .NET Magazine Network.
http://www.winnetmag.com
THIS ISSUE SPONSORED BY
Microsoft ASP.NET Connections & Visual Studio Connections
http://www.devconnections.com
Windows & .NET Magazine Connections
http://www.winconnections.com
(below DEVELOPER .NET PERSPECTIVES)
SPONSOR: MICROSOFT ASP.NET CONNECTIONS & VISUAL STUDIO CONNECTIONS
Microsoft ASP.NET Connections + Visual Studio Connections + SQL Server Magazine Connections equals the largest gathering of Microsoft product architects and independent Tech gurus, delivering four days of hard-core drill-down sessions that you will not find anywhere else.
The Microsoft product team delivers over 35 cutting-edge sessions on the latest product releases. In addition, you can choose from over 100 in-depth sessions presented by our world-class speakers, authors, and consultants who share real-world solutions that will save you months of trial and error.
Visit our expo hall to see the latest technology and have a chance to win a Harley Davidson among other cool give-always. After an intense day of sessions unwind at events like "Microsoft Unplugged," where no question is out of line, or march in the Mardi Gras Parade to the House of Blues for a night to remember.
Register early and get three power-packed events for the price of one. May 6-9, 2003, in New Orleans. For more details, call 800-438-6720 or visit our Web site at
http://www.devconnections.com
February 25, 2003--In this issue:
1. DEVELOPER .NET PERSPECTIVES
Detecting Changes in Application Configuration Settings
2. ANNOUNCEMENTS
Our Active Directory Web Seminar Is in Just 3 Weeks!
SSMU Web Seminar Speakers Make the Difference!
3. NEW AND IMPROVED
Find Framework Applications' Coding Problems
4. CONTACT US
See this section for a list of ways to contact us.
1. DEVELOPER .NET PERSPECTIVES
(contributed by Robin Sanner, [email protected])
DETECTING CHANGES IN APPLICATION CONFIGURATION SETTINGS
Last week, I discussed the common ways to store an application's custom configuration settings, including using the Windows .NET Framework's .config files. I also began to discuss the contents and functionality of .config files.
No matter where you store your application's configuration settings, sooner or later you'll need to retrieve them. In addition, sometimes you'll need to detect changes to the configuration settings as the application is running. Let's look at how you can retrieve configuration settings and how you can dynamically detect changes in those settings.
Retrieving Application Settings
To retrieve configuration settings from your application, you can use the System.Configuration.AppSettingsReader object. Although this object has many methods, only one--the GetValue method--isn't inherited from the System.Object class. The GetValue method retrieves the value of the specified key from the configuration section of the executing assembly.
The first parameter of the GetValue method is the name of the configuration setting found in the key attribute of the XML node. The second parameter is the expected System.Type class (i.e., the data type) of the value stored in the value attribute of the node. For example, to retrieve the value for the connectionString key, which you expect to be a String data type (i.e., the System.String class), you can use the following Visual C# .NET code:
using System.Configuration;AppSettingsReader reader = new AppSettingsReader();string conn = (string)reader.GetValue("connectionString",
typeof(System.String));
Note that although you specify the data type you want returned, the GetValue method returns a System.Object. Thus, you have to cast the returned value into the data type you want. For example, in the above code, the "(string)" cast operator casts the value that reader.GetValue returns into a String data type.
If the specified key doesn't exist or the specified data-type class can't parse the actual value, the GetValue method returns the value InvalidOperationException. Note that I said "parse." The specified data type's Parse method parses the value stored in the value attribute. Keep this point in mind when you set values in the section. The results aren't always what you expect. For example, one result that surprised me was that the Int32.Parse method (the parse method for the "32-bit signed integer" data type) wouldn't parse an empty string as zero. To account for missing or invalid values, you need to handle the InvalidOperationException value accordingly. This way, if a problem exists with the default values or if the .config file is deleted or corrupted, you can still restart your application and rebuild the appropriate defaults in the file.
An advantage to using the AppSettingsReader object is that you don't need to be concerned with the .config file's name or location. Internally, the AppSettingsReader object figures that out for you.
Dynamically Detecting Changes
In non-Framework applications, a common way to dynamically detect changes in configuration settings is to poll at periodic intervals and refresh the settings at each poll interval. However, this practice isn't without problems. If you poll too much, the application's (and possibly the system's) performance declines. If you poll too little, the latency period between when the configuration parameter changed and when the change is actually implemented can cause the application to malfunction.
If the configuration settings are in the registry or an .ini file, you can use the Win32 API as an alternative to polling. You use the Win32 API's RegNotifyChangeKeyValue function if the settings are in the registry. You use the Win32 API's FindFirstChangeNotification function if the settings are in an .ini file. These functions let you set up a change-notification handle that you wait on. When a change in a configuration setting occurs, the functions return a handle to a "find change notification" object. As you can see, the Win32 API approach is simple--no polling threads and no performance penalties.
Unfortunately, detecting changes in Framework applications isn't as easy as detecting changes in non-Framework applications because the Framework doesn't include the entire Win32 API set. In particular, the Framework doesn't include the RegNotifyChangeKeyValue function. Thus, if you store an application's configuration settings in the registry, you must make a Platform Invoke (P/Invoke) call against the Win32 API to use the RegNotifyChangeKeyValue function. You also need to make P/Invoke calls if you want to use other supporting functions, such as RegOpenKey and RegCloseKey. Thankfully, the Framework includes the Win32 API functions that deal with file changes. As a result, you can use the FindFirstChangeNotification function directly (i.e., no P/Invoke calls) to dynamically detect changes in .ini files.
A disadvantage of detecting configuration-setting changes in .config files is that you can't use the AppSettingsReader object. This object doesn't read values from the .config file. When an application first starts, it caches the contents of the .config file; the AppSettingsReader object reads those cached values. So, you must use the System.IO.FileSystemWatcher object to detect changes in a .config file. The FileSystemWatcher object's NotifyFilter property lets you specify the types of changes to watch for. For example, if you want to watch for changes to the last time the file was accessed and written to, you use the LastAccess and LastWrite filters, respectively.
Because a .config file includes many configuration sections, when the FileSystemWatcher object detects a change, you don't know whether the change occurred in the section or another section. Or maybe someone just loaded and saved the file and the file's contents didn't change. This situation points out another difficulty when trying to detect changes in .config files: The detection of changes is at the file level rather than the setting level. In fact, if you configure the FileSystemWatcher object to monitor LastWrite, you'll get two notifications for every file change presumably because the file system applies your change, then updates the file's attributes to reflect when the file changed. If you want to detect which setting changed, you need to load the initial values from the section into an XML document and perform a search in which you compare the section's current values against stored values. By creating a separate object that loads the application's configuration settings into an XML document, you can have the object fire a different event for each value changed. Here's some sample code that loads and stores values from the section into an XML document:
string filename =
AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
FileInfo fileInfo = new FileInfo(fileName);
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(fileInfo.FullName);
XmlNamespaceManager nsMgr = new
XmlNamespaceManager(xmlDocument.NameTable);
XmlNode appSettingsRoot =
xmlDocument.SelectSingleNode("/configuration/appSettings");
XmlNode xmlNode = null;
string searchString = string.Format("add[@key='{0}']", key);
xmlNode = appSettingsRoot.SelectSingleNode(searchString);
XmlNode xmlValue = xmlNode.Attributes.GetNamedItem("value");
Note the way the first block of code obtains the information necessary to locate the .config file--that's all the code you need to use to locate any .config file. You then use the System.Xml.XmlDocument class to create an XML document and use the class's Load method to load the .config file's contents into the XML document. Next, you use XML Path Language (XPath) functions to find the node and retrieve the values you need.
You need to repeat the last block of code for each value you want to retrieve from the .config file. Each time, you must set the "key" variable specified in the second parameter of the string.Format function. That's all you have to modify in that code block for each value you want to retrieve from the configuration file. If you expect the configuration setting to be something other than a string, you need to use the System.Convert class object or the data type's Parse method to convert the incoming string.
Finally, you need to add code that checks whether xmlNode and xmlValue come back null. If xmlNode is null, the specified configuration setting wasn't found. If xmlValue is null, that particular configuration setting is corrupted because all configuration settings in the section should consist of an node with two attributes (i.e., key and value). If you want to implement default values for a specific setting, you can simply store them as constants in the code. Then, if xmlNode is null for that particular setting, the default constant value will be returned instead. You might also go so far as to update the XML code by adding the configuration node with the default value set. If no default value exists, you can then throw the appropriate exception to explain what went wrong. What exception you throw depends on what's missing, but you can always default to throwing a System.ApplicationException exception.
If you're using .config files to store your application's configuration settings, here's the bottom line: If you don't care about changes to the configuration settings as the application is running, you can use the AppSettingsReader object. If you need to detect configuration changes while the application is running, you need to use the FileSystemWatcher object to watch for file changes to the .config file. When a change occurs, you need to load the .config file's contents into an XML document and search for the value that changed.
SPONSOR: WINDOWS & .NET MAGAZINE CONNECTIONS
REAL-WORLD TECHNICAL TIPS HERE FOR YOU
Chock full of "been there, done that" information from experts who use Microsoft technology in the real world. Get the latest tips on Exchange 2000, Exchange 2003, AD basics to advanced, security, wireless networks, Windows 2000, Windows Server 2003, Windows XP, IIS, Group Policy, and more.
Microsoft is sending its "Scripting Guys"--members of its TechNet Script Center who are also responsible for the "Scriptomatic" tool. Don't miss your chance to attend this special one day pre-conference and enhance your scripting skills firsthand from the experts who know Microsoft scripting technologies the best.
For security-minded IT pros, we provide in-depth coverage from the world's top gurus on Windows security: "Keeping Up with Service Packs and Security Patches," "Identity Management with PKI," "Implementing Security with Group Policy," "Securing Wireless LANs," and "Managing AD Security with ADSI and WSH." Other sessions will show you how to defend your networks by planning your own "Hack Attack", how to use event Logs to identify intruder activity, how to make IIS a Secure Web Server, and more.
Don't miss this exclusive opportunity to interact first hand with Windows & .NET Magazine writers you trust: Minasi, Russinovich, Hill, Wells, Deuby, Moskowitz, and more. May 18 - 21 in Scottsdale, AZ. Early registrants save $300, so visit us today at
http://www.winconnections.com
2. ANNOUNCEMENTS
(brought to you by Windows & .NET Magazine and its partners)
OUR ACTIVE DIRECTORY WEB SEMINAR IS IN JUST 3 WEEKS!
Join us as Precise SRM shows you how to leverage Active Directory to assess storage usage, reclaim wasted disk space, and control storage growth. You'll learn how to use AD to save countless hours managing server growth, get back up to half of your server space right away, and even reduce storage growth and backups by 30 percent or more! There is no charge for this event, but space is limited, so register today!
http://www.winnetmag.com/seminars/activedirectory
SSMU WEB SEMINAR SPEAKERS MAKE THE DIFFERENCE!
SQL Server Magazine University (SSMU) Web seminar speakers are tried-and-true people you've come to know and trust through their articles and insights published in SQL Server Magazine. Finally, online training led by SQL Server gurus with real-life business application experience, not just theory! Get complete course info at
http://www.sqlmag.com/sub/webseminar
3. NEW AND IMPROVED
(contributed by Sue Cooper, [email protected])
FIND FRAMEWORK APPLICATIONS' CODING PROBLEMS
Red Gate Software released ANTS Profiler, a code profiler that lets you drill down to examine slow code in Windows .NET Framework applications, quickly pinpointing and explaining any problems, even if the Framework class libraries are causing those problems. The product helps you understand how code works in complex applications so that you can optimize those applications. ANTS Profiler supports any Framework language. Pricing is $195. Contact Red Gate Software at 866-498-9946, (44) (870) 160-0037, or [email protected]://www.red-gate.com
4. CONTACT USHere's how to reach us with your comments and questions:
ABOUT DEVELOPER .NET PERSPECTIVES -- [email protected]
ABOUT THE NEWSLETTER IN GENERAL -- [email protected] (please mention the newsletter name in the subject line)
TECHNICAL QUESTIONS -- http://www.winnetmag.com/forums
PRODUCT NEWS -- [email protected]
QUESTIONS ABOUT YOUR DEVELOPER .NET UPDATE SUBSCRIPTION? Email Customer Support -- [email protected]
WANT TO SPONSOR DEVELOPER .NET UPDATE? [email protected]
This weekly email newsletter is brought to you by Windows & .NET Magazine, the leading publication for Windows professionals who want to learn more and perform better. Subscribe today.
http://www.winnetmag.com/sub.cfm?code=wswi201x1zReceive the latest information about the Windows and .NET topics of your choice. Subscribe to our other FREE email newsletters.
http://www.winnetmag.com/email
About the Author
You May Also Like