Most of us figured out at one time or another that we could use an external source ”a text file, a .ini file, or the registry ”to store external configuration information. Many clever programmers probably stumbled on this as a way to ultimately turn debug information on or off without rebuilding and redeploying an application. Well, now that you have mastered that trick, technology has evolved and we can accomplish the same thing more easily with an XML .config file and a class called BooleanSwitch . What you and I have been doing for years is finally part of the .NET Framework.
We shouldn't judge too harshly, though. For decades developers have been contriving idioms that solve problems and then become a standard part of programming. This is precisely how the Boolean switch evolved.
The BooleanSwitch class reads a .config file. If a value in the .config file indicates that the switch is enabled, the code wrapped within the BooleanSwitch object runs; otherwise the code doesn't run. This is a convenient way to deploy code that contains self-diagnosing features and is probably a reasonable way to ship trialware. For example, make the switch a special Globally Unique Identifier. When the user registers the product, you send them the switch file that enables the trialware to run with all the features.
The basic mechanics of Boolean switches are first to define the entry in an App.config file (or Web.config for Web applications), then declare an instance of the switch in your code and wrap all conditional-run code inside a test determining whether or not the switch is on. To demonstrate in the next two subsections, let's use the BooleanSwitch class to manage the extra trace listener information in the Calculator application's constructor. If we enable the switch, the trace listener is created and used; otherwise, it is not.
Defining a Switch in an Application Configuration File
For Windows applications the .config file is identical to the application's name plus an additional .config extension. For example, the DefaultWindowsDemo.exe application ”the Calculator example ”will look for an application configuration file in the same directory named DefaultWindowsDemo.exe.config . We can create a text file and add the XML directly to that file, but there is an easier way.
If we select the Application Configuration template from the Add New Item dialog, Visual Studio .NET will add an App.config file to the project's source code. When we compile the application, the App.config file will be output with the correct name ” application.ext. config ”in the correct location. All we have to do is add the switch information. Listing 17.7 shows the contents of the .config file with the Boolean switch defined.
Listing 17.7 The Contents of an App.config File for Managing a Boolean Switch
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <switches> <add name="UseListener" value="1" /> </switches> </system.diagnostics> </configuration>
The text set in bold represents the XML that I added. The remainder of the text was added automatically by the Application Configuration template. The <system.diagnostics> tag represents the XML namespace for the switch. The <switches> tag represents the section containing one or more switches, and the <add> tag names the switch and defines its state. For Boolean switches any nonzero value evaluates to an enabled switch; zero represents a disabled switch. You can also use <remove> and <clear> tags. The <remove> tag removes a named switch, and the <clear> tag clears switches defined higher in the configuration section. These might be switches that exist in the App.config file, literally preceding the <clear> tag, or in a .config file that has a larger scope (for example, the machine.config file).
Using a Boolean Switch in an Application
We need only one instance of the System.Diagnostics.BooleanSwitch class; all code in the same application can share that instance. After we initialize the shared BooleanSwitch object ”to provide access to all interested code ”we only need to check the Enabled property in a conditional statement to determine whether our switch is enabled. Listing 17.8 demonstrates a revision to the constructor from Listing 17.5, using the shared BooleanSwitch object to determine whether the TraceListener object should be created and added to the Listeners collection.
Listing 17.8 Using a Boolean Switch to Manage Debug Code after Compiling and Deploying
Private Shared Switch As BooleanSwitch _ = New BooleanSwitch("UseListener", "Manage Trace Listeners") Public Sub New() If (Not Switch.Enabled) Then Exit Sub Dim Listener As EventLogTraceListener = _ New EventLogTraceListener("Calculator") Trace.Listeners.Add(Listener) Trace.WriteLine("Calculator Constructor") End Sub
The BooleanSwitch object is defined as shared in the first statement. Notice that the first parameter matches the name of the switch from Listing 17.7. (Case is not important for the switch name, but I try to match the case as well as the name.) The first statement in the constructor uses what I refer to as a sentry . The sentry works like a guard at a checkpoint who says, "The eagle soars" and lets you pass only if you respond, "Ever higher on a thermal." However, in this case the sentry allows admittance only if the BooleanSwitch object is enabled.
You can use as many switches as you need or want. Simply define more switches in the .config file and instantiate a like number of BooleanSwitch objects in your code. Using Boolean switches is an excellent way to manage optional features, debug code, or some kind of diagnostics code after you build and deploy your application because all you need is a text editor to turn the switch ”and by association the code ”off or on. Note that you can use Boolean switches to manage Windows, console, and Web application code.