The Labs \ Source Viewer \ SSCLI \ System.Diagnostics \ Switch

  1. //------------------------------------------------------------------------------
  2. // <copyright file="Switch.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. /*
  16. */
  17. namespace System.Diagnostics
  18. {
  19.     using System;
  20.     using System.Security;
  21.     using System.Security.Permissions;
  22.     using System.Threading;
  23.     using System.Runtime.InteropServices;
  24.     using Microsoft.Win32;
  25.     using System.Collections;
  26.     using System.Collections.Generic;
  27.     using System.Collections.Specialized;
  28.     using System.Globalization;
  29.     using System.Configuration;
  30.     using System.Xml.Serialization;
  31.    
  32.     /// <devdoc>
  33.     /// <para>Provides an <see langword='abstract '/>base class to
  34.     /// create new debugging and tracing switches.</para>
  35.     /// </devdoc>
  36.     public abstract class Switch
  37.     {
  38.         private SwitchElementsCollection switchSettings;
  39.         private string description;
  40.         private string displayName;
  41.         private int switchSetting = 0;
  42.         private bool initialized = false;
  43.         private bool initializing = false;
  44.         private string switchValueString = String.Empty;
  45.         private StringDictionary attributes;
  46.         private string defaultValue;
  47.        
  48.         private static List<WeakReference> switches = new List<WeakReference>();
  49.        
  50.         /// <devdoc>
  51.         /// <para>Initializes a new instance of the <see cref='System.Diagnostics.Switch'/>
  52.         /// class.</para>
  53.         /// </devdoc>
  54.         protected Switch(string displayName, string description) : this(displayName, description, "0")
  55.         {
  56.         }
  57.        
  58.         protected Switch(string displayName, string description, string defaultSwitchValue)
  59.         {
  60.             // displayName is used as a hashtable key, so it can never
  61.             // be null.
  62.             if (displayName == null)
  63.                 displayName = string.Empty;
  64.            
  65.             this.displayName = displayName;
  66.             this.description = description;
  67.            
  68.             lock (switches) {
  69.                 switches.Add(new WeakReference(this));
  70.             }
  71.            
  72.             defaultValue = defaultSwitchValue;
  73.         }
  74.        
  75.         [XmlIgnore()]
  76.         public StringDictionary Attributes {
  77.             get {
  78.                 Initialize();
  79.                 if (attributes == null)
  80.                     attributes = new StringDictionary();
  81.                 return attributes;
  82.             }
  83.         }
  84.        
  85.         /// <devdoc>
  86.         /// <para>Gets a name used to identify the switch.</para>
  87.         /// </devdoc>
  88.         public string DisplayName {
  89.             get { return displayName; }
  90.         }
  91.        
  92.         /// <devdoc>
  93.         /// <para>Gets a description of the switch.</para>
  94.         /// </devdoc>
  95.         public string Description {
  96.             get { return (description == null) ? string.Empty : description; }
  97.         }
  98.        
  99.         /// <devdoc>
  100.         /// <para>
  101.         /// Indicates the current setting for this switch.
  102.         /// </para>
  103.         /// </devdoc>
  104.         protected int SwitchSetting {
  105.             get {
  106.                 if (!initialized) {
  107.                     if (!InitializeWithStatus())
  108.                         return 0;
  109.                     OnSwitchSettingChanged();
  110.                 }
  111.                 return switchSetting;
  112.             }
  113.             set {
  114.                 initialized = true;
  115.                 if (switchSetting != value) {
  116.                     switchSetting = value;
  117.                     OnSwitchSettingChanged();
  118.                 }
  119.             }
  120.         }
  121.        
  122.         protected string Value {
  123.             get {
  124.                 Initialize();
  125.                 return switchValueString;
  126.             }
  127.             set {
  128.                 Initialize();
  129.                 switchValueString = value;
  130.                 try {
  131.                     OnValueChanged();
  132.                 }
  133.                 catch (ArgumentException e) {
  134.                     throw new ConfigurationErrorsException(SR.GetString(SR.BadConfigSwitchValue, DisplayName), e);
  135.                 }
  136.                 catch (FormatException e) {
  137.                     throw new ConfigurationErrorsException(SR.GetString(SR.BadConfigSwitchValue, DisplayName), e);
  138.                 }
  139.                 catch (OverflowException e) {
  140.                     throw new ConfigurationErrorsException(SR.GetString(SR.BadConfigSwitchValue, DisplayName), e);
  141.                 }
  142.             }
  143.         }
  144.        
  145.         private void Initialize()
  146.         {
  147.             InitializeWithStatus();
  148.         }
  149.        
  150.         private bool InitializeWithStatus()
  151.         {
  152.             if (!initialized) {
  153.                
  154.                 if (initializing)
  155.                     return false;
  156.                
  157.                 initializing = true;
  158.                
  159.                 if (switchSettings == null) {
  160.                     if (!InitializeConfigSettings())
  161.                         return false;
  162.                 }
  163.                
  164.                 if (switchSettings != null) {
  165.                     SwitchElement mySettings = switchSettings[displayName];
  166.                     if (mySettings != null) {
  167.                         string value = mySettings.Value;
  168.                         if (value != null) {
  169.                             this.Value = value;
  170.                         }
  171.                         else
  172.                             this.Value = defaultValue;
  173.                        
  174.                         try {
  175.                             TraceUtils.VerifyAttributes(mySettings.Attributes, GetSupportedAttributes(), this);
  176.                         }
  177.                         catch (ConfigurationException) {
  178.                             // if VerifyAttributes throws, clean up a little bit so we're not in a bad state.
  179.                             initialized = false;
  180.                             initializing = false;
  181.                             throw;
  182.                         }
  183.                        
  184.                         attributes = new StringDictionary();
  185.                         attributes.contents = mySettings.Attributes;
  186.                     }
  187.                     else {
  188.                         // We don't use the property here because we don't want to catch exceptions
  189.                         // and rethrow them as ConfigurationException. In this case there's no config.
  190.                         switchValueString = defaultValue;
  191.                         OnValueChanged();
  192.                     }
  193.                 }
  194.                 else {
  195.                     // We don't use the property here because we don't want to catch exceptions
  196.                     // and rethrow them as ConfigurationException. In this case there's no config.
  197.                     switchValueString = defaultValue;
  198.                     OnValueChanged();
  199.                 }
  200.                
  201.                 initialized = true;
  202.                 initializing = false;
  203.             }
  204.            
  205.             return true;
  206.         }
  207.        
  208.         private bool InitializeConfigSettings()
  209.         {
  210.             if (switchSettings != null)
  211.                 return true;
  212.            
  213.             if (!DiagnosticsConfiguration.CanInitialize())
  214.                 return false;
  215.            
  216.             // This hashtable is case-insensitive.
  217.             switchSettings = DiagnosticsConfiguration.SwitchSettings;
  218.             return true;
  219.         }
  220.        
  221.         protected internal virtual string[] GetSupportedAttributes()
  222.         {
  223.             return null;
  224.         }
  225.        
  226.         /// <devdoc>
  227.         /// This method is invoked when a switch setting has been changed. It will
  228.         /// be invoked the first time a switch reads its value from the registry
  229.         /// or environment, and then it will be invoked each time the switch's
  230.         /// value is changed.
  231.         /// </devdoc>
  232.         protected virtual void OnSwitchSettingChanged()
  233.         {
  234.         }
  235.        
  236.         protected virtual void OnValueChanged()
  237.         {
  238.             SwitchSetting = Int32.Parse(Value, CultureInfo.InvariantCulture);
  239.         }
  240.        
  241.         static internal void RefreshAll()
  242.         {
  243.            
  244.             lock (switches) {
  245.                 for (int i = 0; i < switches.Count; i++) {
  246.                     Switch swtch = ((Switch)switches[i].Target);
  247.                     if (swtch != null) {
  248.                         swtch.Refresh();
  249.                     }
  250.                 }
  251.             }
  252.         }
  253.        
  254.         internal void Refresh()
  255.         {
  256.             initialized = false;
  257.             switchSettings = null;
  258.             Initialize();
  259.         }
  260.        
  261.     }
  262. }

Developer Fusion