Recipe8.3.Creating Your Own Custom Switch Class


Recipe 8.3. Creating Your Own Custom Switch Class

Problem

The BooleanSwitch and traceSwitch classes defined in the FCL may not always have the required flexibility or fine-grained control that you need. You want to create a switch class that provides more control and flexibility. For example, you might want to create a class that allows you to set more precise trace levels than those supported by the traceSwitch class, which are:

 TraceError TraceWarning TraceInfo TraceVerbose 

However, you need a finer-grained set of levels, such as those shown in Table 8-2.

Table 8-2. A set of custom trace levels

Disable

MinorError

Note

MediumError

Warning

CriticalError


Solution

You can create your own switch class that inherits from System.Diagnostics.Switch and provides the level of control that you need. For example, creating a class that allows you to set more precise trace levels than those supported by the traceSwitch class involves the following steps:

  1. Define a set of enumerated values that represent the levels to be supported by your switch class. The following definition implements the levels listed in Table 8-2:

     public enum AppSpecificSwitchLevel {     Disable = 0,     Note = 1,     Warning = 2,     MinorError = 3,     MediumError = 4,     CriticalError = 5 } 

  2. Define a class, such as AppSpecificSwitch (shown in Example 8-1), that inherits from System.Diagnostics.Switch and sets your own levels.

    Example 8-1. AppSpecificSwitch, a custom switch class

     public class AppSpecificSwitch : Switch {      protected AppSpecificSwitchLevel level = 0;      public AppSpecificSwitch(string displayName, string description)          : base(displayName, description) {          Level = (AppSpecificSwitchLevel)base.SwitchSetting; } // Read/write Level property public AppSpecificSwitchLevel Level {     get     {         return level;     }     set     {         if (value < AppSpecificSwitchLevel.Disable)         {             level = AppSpecificSwitchLevel.Disable;         }         else if (value > AppSpecificSwitchLevel.CriticalError)         {             level = AppSpecificSwitchLevel.CriticalError;         }         else         {             level = value;         }     } } // Read-only properties for the AppSpecificSwitchLevel enum public bool Disable {     get     {         if (level <= AppSpecificSwitchLevel.Disable)         {             return (true);         }         else         {             return (false);         }     } } public bool Note {     get     {         if (level <= AppSpecificSwitchLevel.Note)         {             return (true);         }         else         {             return (false);         }     } } public bool Warning {     get     {             if (level <= AppSpecificSwitchLevel.Warning)             {                 return (true);             }             else             {                 return (false);             }         }     }     public bool MinorError     {         get         {             if (level <= AppSpecificSwitchLevel.MinorError)             {                 return (true);             }             else             {                 return (false);             }         }     }     public bool MediumError     {         get         {             if (level <= AppSpecificSwitchLevel.MediumError)             {                 return (true);             }             else             {                 return (false);             }         }     }     public bool CriticalError     {         get         {             if (level <= AppSpecificSwitchLevel.CriticalError)             {                 return (true);             }             else             {                 return (false);             }         }     } } 

  3. In code, you can instantiate this custom class by invoking its constructor:

     AppSpecificSwitch appSwitch = new AppSpecificSwitch("MyApplication",                               "My Application Specific Switch"); 

  4. Set the switch in the application configuration file. For example, the following configuration file sets the level of your custom switch to AppSpecificSwitchLevel.CriticalLevel:

     <?xml version="1.0" encoding="utf-8" ?> <configuration>     <system.diagnostics>         <switches>             <add name="MyApplication" value="5" />         </switches>     </system.diagnostics> </configuration> 

More information on configuration files can be found in Recipes 8.1 and 8.2.

Discussion

The BooleanSwitch and traceSwitch classes defined in the FCL might not always have the flexibility that you need. In these cases, you can create a class that inherits from the Switch classthe abstract base class of all switch type classes.

The critical part of creating a custom switch class is the constructor. The constructor must call its base class constructor using the :base() syntax. If this syntax is omitted, a compiler error will appear, indicating that there is no default constructor to call on the base class Switch. You might notice that the Switch class contains a single public constructor that accepts two string parameters. This is designed so that you must use this constructor when building an object of this type or any type derived from it. Calling the base class's constructor also allows the application configuration file to be searched, if one exists, for any initialization value for this switch object.

You can circumvent the configuration file search by writing the constructor as follows:

 public AppSpecificSwitch(string displayName, string description)     : base("", description) {     this.Level = (AppSpecificSwitchLevel)base.SwitchSetting; } 

The other item of interest in this constructor is the one line of code in its body. This line of code grabs the level information acquired from the application configuration file and sets this inherited class's Level property to this value. This line is required because the base class is the one that receives the initialization information from a configuration file, not the inherited class.

This class contains several other properties. The first is the Level property, which gets and sets the current level of this object. The levels are defined in the AppSpecificSwitchLevel enumeration. This class also contains a read-only property for each element in the AppSpecificSwitchLevel enumeration. These can be used to query this object to determine whether its various levels are set.

See Also

See Recipes 8.1 and 8.2; see the "Switch Class" and "Trace and debug Settings Schema" topics in the MSDN documentation.



C# Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2004
Pages: 424

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net