改造Duwamish中的Configuration
使用了泛型修改了Duwamish中Configuration的Handler
写了一个处理键/值配置节的处理类:
public class NameValueConfigurationHanderBase<T> : NameValueSectionHandler where T : NameValueConfigurationHanderBase<T>
{
private static Dictionary<Type, NameValueCollection>
_settingsCollection = new Dictionary<Type, NameValueCollection>();
private static NameValueCollection Settings
{
get
{
if (_settingsCollection.ContainsKey(ConfigurationHanderType) == false)
{
_settingsCollection.Add(ConfigurationHanderType,
(NameValueCollection)ConfigurationManager.GetSection(ConfigurationSectionName));
}
else if (_settingsCollection[ConfigurationHanderType] == null)
{
_settingsCollection[ConfigurationHanderType] = (NameValueCollection)
ConfigurationManager.GetSection(ConfigurationSectionName);
}
return _settingsCollection[ConfigurationHanderType];
}
}
private static Type ConfigurationHanderType
{
get
{
return typeof(T);
}
}
private static String ConfigurationSectionName
{
get
{
ConfigurationSectionNameAttribute[] attributes = (ConfigurationSectionNameAttribute[])
ConfigurationHanderType.GetCustomAttributes(typeof(ConfigurationSectionNameAttribute), false);
if (attributes.Length == 1)
{
return attributes[0].Name;
}
else
{
return null;
}
}
}
public static U ReadSetting<U>(String key, U defaultValue, Converter<String, U> converter)
{
try
{
String setting = Settings[key];
return (setting == null) ? defaultValue : converter(setting);
}
catch
{
return defaultValue;
}
}
/**//// <summary>
/// String version of ReadSetting.
/// <remarks>
/// Reads a setting from a hashtable and converts it to the correct
/// type. One of these functions is provided for each type
/// expected in the hash table. These are public so that other
/// classes don't have to duplicate them to read settings from
/// a hash table.
/// </remarks>
/// <param name="key">A key for the value in the Hashtable.</param>
/// <param name="defaultValue">The default value if the item is not found.</param>
/// <retvalue>
/// <para>value: from the hash table</para>
/// <para>
/// default: if the item is not in the table or cannot be case to the expected type.
/// </para>
/// </retvalue>
/// </summary>
public static String ReadSetting(String key, String defaultValue)
{
try
{
Object setting = Settings[key];
return (setting == null) ? defaultValue : (String)setting;
}
catch
{
return defaultValue;
}
}
/**//// <summary>
/// Boolean version of ReadSetting.
/// <remarks>
/// Reads a setting from a hashtable and converts it to the correct
/// type. One of these functions is provided for each type
/// expected in the hash table. These are public so that other
/// classes don't have to duplicate them to read settings from
/// a hash table.
/// </remarks>
/// <param name="key">A key for the value in the Hashtable.</param>
/// <param name="defaultValue">The default value if the item is not found.</param>
/// <retvalue>
/// <para>value: from the hash table</para>
/// <para>
/// default: if the item is not in the table or cannot be case to the expected type.
/// </para>
/// </retvalue>
/// </summary>
public static bool ReadSetting(String key, bool defaultValue)
{
try
{
Object setting = Settings[key];
return (setting == null) ? defaultValue : Convert.ToBoolean((String)setting);
}
catch
{
return defaultValue;
}
}
/**//// <summary>
/// int version of ReadSetting.
/// <remarks>
/// Reads a setting from a hashtable and converts it to the correct
/// type. One of these functions is provided for each type
/// expected in the hash table. These are public so that other
/// classes don't have to duplicate them to read settings from
/// a hash table.
/// </remarks>
/// <param name="key">A key for the value in the Hashtable.</param>
/// <param name="defaultValue">The default value if the item is not found.</param>
/// <retvalue>
/// <para>value: from the hash table</para>
/// <para>
/// default: if the item is not in the table or cannot be case to the expected type.
/// </para>
/// </retvalue>
/// </summary>
public static int ReadSetting(String key, int defaultValue)
{
try
{
Object setting = Settings[key];
return (setting == null) ? defaultValue : Convert.ToInt32((String)setting);
}
catch
{
return defaultValue;
}
}
/**//// <summary>
/// TraceLevel version of ReadSetting.
/// <remarks>
/// Reads a setting from a hashtable and converts it to the correct
/// type. One of these functions is provided for each type
/// expected in the hash table. These are public so that other
/// classes don't have to duplicate them to read settings from
/// a hash table.
/// </remarks>
/// <param name="key">A key for the value in the Hashtable.</param>
/// <param name="defaultValue">The default value if the item is not found.</param>
/// <retvalue>
/// <para>value: from the hash table</para>
/// <para>
/// default: if the item is not in the table or cannot be case to the expected type.
/// </para>
/// </retvalue>
/// </summary>
public static TraceLevel ReadSetting(String key, TraceLevel defaultValue)
{
try
{
Object setting = Settings[key];
return (setting == null) ? defaultValue : (TraceLevel)Convert.ToInt32((String)setting);
}
catch
{
return defaultValue;
}
}
}
继承类(功能简化了):
/**//// <summary>
/// System Framework Configuration
/// </summary>
[ConfigurationSectionName("system.framework")]
public class FrameworkConfiguration : NameValueConfigurationHanderBase<FrameworkConfiguration>
{
//
// Constant values for all of the SystemFramework standard settings
//
private const String TRACING_ENABLED = "SystemFramework.Tracing.Enabled";
private const String TRACING_TRACEFILE = "SystemFramework.Tracing.TraceFile";
private const String TRACING_TRACELEVEL = "SystemFramework.Tracing.TraceLevel";
private const String TRACING_SWITCHNAME = "SystemFramework.Tracing.SwitchName";
private const String TRACING_SWITCHDESCRIPTION = "SystemFramework.Tracing.SwitchDescription";
private const String EVENTLOG_ENABLED = "SystemFramework.EventLog.Enabled";
private const String EVENTLOG_MACHINENAME = "SystemFramework.EventLog.Machine";
private const String EVENTLOG_SOURCENAME = "SystemFramework.EventLog.SourceName";
private const String EVENTLOG_TRACELEVEL = "SystemFramework.EventLog.LogLevel";
//
// Constant values for all of the default settings.
//
private const bool TRACING_ENABLED_DEFAULT = true;
private const String TRACING_TRACEFILE_DEFAULT = "ApplicationTrace.txt";
private const TraceLevel TRACING_TRACELEVEL_DEFAULT = TraceLevel.Verbose;
private const String TRACING_SWITCHNAME_DEFAULT = "ApplicationTraceSwitch";
private const String TRACING_SWITCHDESCRIPTION_DEFAULT = "Application error and tracing information";
private const bool EVENTLOG_ENABLED_DEFAULT = true;
private const String EVENTLOG_MACHINENAME_DEFAULT = ".";
private const String EVENTLOG_SOURCENAME_DEFAULT = "WebApplication";
private const TraceLevel EVENTLOG_TRACELEVEL_DEFAULT = TraceLevel.Error;
/**//// <value>
/// Property TracingEnabled is used to get the configuration setting, defaulting to False on error.
/// </value>
public static bool TracingEnabled
{
get
{
return ReadSetting(TRACING_ENABLED, TRACING_ENABLED_DEFAULT) ;
}
}
/**//// <value>
/// Property TracingTraceFile is used to get the full path name to the file that contains trace
/// defaults to ApplicationTrace.txt.
/// </value>
public static String TracingTraceFile
{
get
{
return ReadSetting(TRACING_TRACEFILE, TRACING_TRACEFILE_DEFAULT);
}
}
/**//// <value>
/// Property TracingTraceFile is used to get the highest logging level that should be written to
/// the tracing file, defaults to TraceLevel.Verbose (however, TracingEnabled defaults
/// to False, so you have to turn it on explicitly).
/// </value>
public static TraceLevel TracingTraceLevel
{
get
{
return ReadSetting(TRACING_TRACELEVEL, TRACING_TRACELEVEL_DEFAULT);
}
}
/**//// <value>
/// Property TracingSwitchName is used to get the trace switch name, defaults to ApplicationTraceSwitch.
/// </value>
public static String TracingSwitchName
{
get
{
return ReadSetting(TRACING_SWITCHNAME, TRACING_SWITCHNAME_DEFAULT);
}
}
/**//// <value>
/// Property TracingSwitchDescription is used to get the trace settings file, defaults to
/// "Application error and tracing information".
/// </value>
public static String TracingSwitchDescription
{
get
{
return ReadSetting(TRACING_SWITCHDESCRIPTION, TRACING_SWITCHDESCRIPTION_DEFAULT);
}
}
/**//// <value>
/// Property EventLogEnabled is used to get whether writing to the event log is support, defaults to True.
/// <remarks>Returns true if writing to the event log is enabled, false otherwise</remarks>
/// </value>
public static bool EventLogEnabled
{
get
{
return ReadSetting(EVENTLOG_ENABLED, EVENTLOG_ENABLED_DEFAULT);
}
}
/**//// <value>
/// Property EventLogMachineName is used to get the machine name to log the event to, defaults to an
/// empty string, indicating the current machine. A machine name
/// (without \\), may be empty.
/// </value>
public static String EventLogMachineName
{
get
{
return ReadSetting(EVENTLOG_MACHINENAME, EVENTLOG_MACHINENAME_DEFAULT);
}
}
/**//// <value>
/// Property EventLogMachineName is used to get the source of the error to be written to the event log,
/// defaults WebApplication.
/// </value>
public static String EventLogSourceName
{
get
{
return ReadSetting(EVENTLOG_SOURCENAME, EVENTLOG_SOURCENAME_DEFAULT);
}
}
/**//// <value>
/// Property EventLogTraceLevel is used to get the highest logging level that should be written to the event log,
/// defaults to TraceLevel.Error.
/// </value>
public static TraceLevel EventLogTraceLevel
{
get
{
return ReadSetting(EVENTLOG_TRACELEVEL, EVENTLOG_TRACELEVEL_DEFAULT);
}
}
}
其他的配置节:
public class NameValueConfigurationHanderBase<T> : NameValueSectionHandler where T : NameValueConfigurationHanderBase<T>
{
private static Dictionary<Type, NameValueCollection>
_settingsCollection = new Dictionary<Type, NameValueCollection>();
private static NameValueCollection Settings
{
get
{
if (_settingsCollection.ContainsKey(ConfigurationHanderType) == false)
{
_settingsCollection.Add(ConfigurationHanderType,
(NameValueCollection)ConfigurationManager.GetSection(ConfigurationSectionName));
}
else if (_settingsCollection[ConfigurationHanderType] == null)
{
_settingsCollection[ConfigurationHanderType] = (NameValueCollection)
ConfigurationManager.GetSection(ConfigurationSectionName);
}
return _settingsCollection[ConfigurationHanderType];
}
}
private static Type ConfigurationHanderType
{
get
{
return typeof(T);
}
}
private static String ConfigurationSectionName
{
get
{
ConfigurationSectionNameAttribute[] attributes = (ConfigurationSectionNameAttribute[])
ConfigurationHanderType.GetCustomAttributes(typeof(ConfigurationSectionNameAttribute), false);
if (attributes.Length == 1)
{
return attributes[0].Name;
}
else
{
return null;
}
}
}
public static U ReadSetting<U>(String key, U defaultValue, Converter<String, U> converter)
{
try
{
String setting = Settings[key];
return (setting == null) ? defaultValue : converter(setting);
}
catch
{
return defaultValue;
}
}
/**//// <summary>
/// String version of ReadSetting.
/// <remarks>
/// Reads a setting from a hashtable and converts it to the correct
/// type. One of these functions is provided for each type
/// expected in the hash table. These are public so that other
/// classes don't have to duplicate them to read settings from
/// a hash table.
/// </remarks>
/// <param name="key">A key for the value in the Hashtable.</param>
/// <param name="defaultValue">The default value if the item is not found.</param>
/// <retvalue>
/// <para>value: from the hash table</para>
/// <para>
/// default: if the item is not in the table or cannot be case to the expected type.
/// </para>
/// </retvalue>
/// </summary>
public static String ReadSetting(String key, String defaultValue)
{
try
{
Object setting = Settings[key];
return (setting == null) ? defaultValue : (String)setting;
}
catch
{
return defaultValue;
}
}
/**//// <summary>
/// Boolean version of ReadSetting.
/// <remarks>
/// Reads a setting from a hashtable and converts it to the correct
/// type. One of these functions is provided for each type
/// expected in the hash table. These are public so that other
/// classes don't have to duplicate them to read settings from
/// a hash table.
/// </remarks>
/// <param name="key">A key for the value in the Hashtable.</param>
/// <param name="defaultValue">The default value if the item is not found.</param>
/// <retvalue>
/// <para>value: from the hash table</para>
/// <para>
/// default: if the item is not in the table or cannot be case to the expected type.
/// </para>
/// </retvalue>
/// </summary>
public static bool ReadSetting(String key, bool defaultValue)
{
try
{
Object setting = Settings[key];
return (setting == null) ? defaultValue : Convert.ToBoolean((String)setting);
}
catch
{
return defaultValue;
}
}
/**//// <summary>
/// int version of ReadSetting.
/// <remarks>
/// Reads a setting from a hashtable and converts it to the correct
/// type. One of these functions is provided for each type
/// expected in the hash table. These are public so that other
/// classes don't have to duplicate them to read settings from
/// a hash table.
/// </remarks>
/// <param name="key">A key for the value in the Hashtable.</param>
/// <param name="defaultValue">The default value if the item is not found.</param>
/// <retvalue>
/// <para>value: from the hash table</para>
/// <para>
/// default: if the item is not in the table or cannot be case to the expected type.
/// </para>
/// </retvalue>
/// </summary>
public static int ReadSetting(String key, int defaultValue)
{
try
{
Object setting = Settings[key];
return (setting == null) ? defaultValue : Convert.ToInt32((String)setting);
}
catch
{
return defaultValue;
}
}
/**//// <summary>
/// TraceLevel version of ReadSetting.
/// <remarks>
/// Reads a setting from a hashtable and converts it to the correct
/// type. One of these functions is provided for each type
/// expected in the hash table. These are public so that other
/// classes don't have to duplicate them to read settings from
/// a hash table.
/// </remarks>
/// <param name="key">A key for the value in the Hashtable.</param>
/// <param name="defaultValue">The default value if the item is not found.</param>
/// <retvalue>
/// <para>value: from the hash table</para>
/// <para>
/// default: if the item is not in the table or cannot be case to the expected type.
/// </para>
/// </retvalue>
/// </summary>
public static TraceLevel ReadSetting(String key, TraceLevel defaultValue)
{
try
{
Object setting = Settings[key];
return (setting == null) ? defaultValue : (TraceLevel)Convert.ToInt32((String)setting);
}
catch
{
return defaultValue;
}
}
}
继承类(功能简化了):
/**//// <summary>
/// System Framework Configuration
/// </summary>
[ConfigurationSectionName("system.framework")]
public class FrameworkConfiguration : NameValueConfigurationHanderBase<FrameworkConfiguration>
{
//
// Constant values for all of the SystemFramework standard settings
//
private const String TRACING_ENABLED = "SystemFramework.Tracing.Enabled";
private const String TRACING_TRACEFILE = "SystemFramework.Tracing.TraceFile";
private const String TRACING_TRACELEVEL = "SystemFramework.Tracing.TraceLevel";
private const String TRACING_SWITCHNAME = "SystemFramework.Tracing.SwitchName";
private const String TRACING_SWITCHDESCRIPTION = "SystemFramework.Tracing.SwitchDescription";
private const String EVENTLOG_ENABLED = "SystemFramework.EventLog.Enabled";
private const String EVENTLOG_MACHINENAME = "SystemFramework.EventLog.Machine";
private const String EVENTLOG_SOURCENAME = "SystemFramework.EventLog.SourceName";
private const String EVENTLOG_TRACELEVEL = "SystemFramework.EventLog.LogLevel";
//
// Constant values for all of the default settings.
//
private const bool TRACING_ENABLED_DEFAULT = true;
private const String TRACING_TRACEFILE_DEFAULT = "ApplicationTrace.txt";
private const TraceLevel TRACING_TRACELEVEL_DEFAULT = TraceLevel.Verbose;
private const String TRACING_SWITCHNAME_DEFAULT = "ApplicationTraceSwitch";
private const String TRACING_SWITCHDESCRIPTION_DEFAULT = "Application error and tracing information";
private const bool EVENTLOG_ENABLED_DEFAULT = true;
private const String EVENTLOG_MACHINENAME_DEFAULT = ".";
private const String EVENTLOG_SOURCENAME_DEFAULT = "WebApplication";
private const TraceLevel EVENTLOG_TRACELEVEL_DEFAULT = TraceLevel.Error;
/**//// <value>
/// Property TracingEnabled is used to get the configuration setting, defaulting to False on error.
/// </value>
public static bool TracingEnabled
{
get
{
return ReadSetting(TRACING_ENABLED, TRACING_ENABLED_DEFAULT) ;
}
}
/**//// <value>
/// Property TracingTraceFile is used to get the full path name to the file that contains trace
/// defaults to ApplicationTrace.txt.
/// </value>
public static String TracingTraceFile
{
get
{
return ReadSetting(TRACING_TRACEFILE, TRACING_TRACEFILE_DEFAULT);
}
}
/**//// <value>
/// Property TracingTraceFile is used to get the highest logging level that should be written to
/// the tracing file, defaults to TraceLevel.Verbose (however, TracingEnabled defaults
/// to False, so you have to turn it on explicitly).
/// </value>
public static TraceLevel TracingTraceLevel
{
get
{
return ReadSetting(TRACING_TRACELEVEL, TRACING_TRACELEVEL_DEFAULT);
}
}
/**//// <value>
/// Property TracingSwitchName is used to get the trace switch name, defaults to ApplicationTraceSwitch.
/// </value>
public static String TracingSwitchName
{
get
{
return ReadSetting(TRACING_SWITCHNAME, TRACING_SWITCHNAME_DEFAULT);
}
}
/**//// <value>
/// Property TracingSwitchDescription is used to get the trace settings file, defaults to
/// "Application error and tracing information".
/// </value>
public static String TracingSwitchDescription
{
get
{
return ReadSetting(TRACING_SWITCHDESCRIPTION, TRACING_SWITCHDESCRIPTION_DEFAULT);
}
}
/**//// <value>
/// Property EventLogEnabled is used to get whether writing to the event log is support, defaults to True.
/// <remarks>Returns true if writing to the event log is enabled, false otherwise</remarks>
/// </value>
public static bool EventLogEnabled
{
get
{
return ReadSetting(EVENTLOG_ENABLED, EVENTLOG_ENABLED_DEFAULT);
}
}
/**//// <value>
/// Property EventLogMachineName is used to get the machine name to log the event to, defaults to an
/// empty string, indicating the current machine. A machine name
/// (without \\), may be empty.
/// </value>
public static String EventLogMachineName
{
get
{
return ReadSetting(EVENTLOG_MACHINENAME, EVENTLOG_MACHINENAME_DEFAULT);
}
}
/**//// <value>
/// Property EventLogMachineName is used to get the source of the error to be written to the event log,
/// defaults WebApplication.
/// </value>
public static String EventLogSourceName
{
get
{
return ReadSetting(EVENTLOG_SOURCENAME, EVENTLOG_SOURCENAME_DEFAULT);
}
}
/**//// <value>
/// Property EventLogTraceLevel is used to get the highest logging level that should be written to the event log,
/// defaults to TraceLevel.Error.
/// </value>
public static TraceLevel EventLogTraceLevel
{
get
{
return ReadSetting(EVENTLOG_TRACELEVEL, EVENTLOG_TRACELEVEL_DEFAULT);
}
}
}
其他的配置节:
/**//// <summary>
///
/// </summary>
[ConfigurationSectionName("application.configuration")]
class ApplicationConfiguration : NameValueConfigurationHanderBase<ApplicationConfiguration>
{
}
///
/// </summary>
[ConfigurationSectionName("application.configuration")]
class ApplicationConfiguration : NameValueConfigurationHanderBase<ApplicationConfiguration>
{
}