# Possible solutions to remove the use of a Hashtable

While this is working very well for storing setting variables for my applications, I've been using it for a number of years and really feel there is something better. I'm perhaps just looking to use some newer functions from the framework.

    public string Value { get; set; }
public string Name { get; set; }
public string Notes { get; set; }

/// <summary>
/// Gets the selected setting from cache if it exists,
///     else returns the supplied default value
/// </summary>
/// <param name="settingName"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static string GetCacheSetting(string settingName, string defaultValue)
{
}

/// <summary>
/// Returns the selected setting value from cache.
/// If cache is null then rebuild the cache.
/// </summary>
/// <returns></returns>
{
Hashtable h;
h = (Hashtable)HttpRuntime.Cache["SiteSettings"];

if (h == null)
{
h = new Hashtable();

DataAccess da = new DataAccess(); //My DAL

foreach (DataRow row in da.GetSiteSettings().Tables[0].Rows)
{
Settings oSetting = new Settings();
oSetting.SettingsInitFromRow(row);
}

HttpRuntime.Cache.Insert("SiteSettings",
h,
null,
Cache.NoSlidingExpiration);
}

return h;
}

/// <summary>
/// Sets the values for the cache items
/// </summary>
/// <param name="row"></param>
private void SettingsInitFromRow(DataRow row)
{
this.Name = (string)row["Name"];
this.Value = (string)row["Value"];
}


The settings are stored in the database and created at install time/modified as needed. At most I have 20 to 30 setting values in the database. I'm using a Hashtable stored in cache to get my values to remove the need to access the database 2, 3, or more times on every page load just for settings in addition to the rest of the times for page content. Doing this was the last time I majorly changed it maybe 3 years ago.

Any ideas?

It look spretty good to me, but there are a couple of things I would likely change, none of which have to do with the use (or non-use) of a hashtable data structure as it is perfectly suited for this sort of thing.

I would probably change the LoadSettings method a bit as it doesn't actually load settings each time it is called, and then definitely use the generic Dictionary<K,V> instead of the antiquated Hashtable class, thereby removing the need for all that nasty casting. You could also avoid two lookups when attempting to retrieve a value from the cache by using TryGetValue instead of Contains and then performing another lookup, something like:

public static string GetCacheSetting(string settingName, string defaultValue)
{
string ret;
Settings.TryGetValue( settingName, out ret );
return ret ?? defaultValue;
}

// you may even want to make this private as a caller could
// edit the contents of the cache directly.  You could leave
// GetCacheSetting as the only access point, adding a
// SetCacheSetting method if needed.
private static Dictionary<string, string> _settings;
public static Dictionary<string, string> Settings
{
get
{
if( _settings == null )
{
}

return _settings;
}
}

{
HttpRuntime.Cache.Remove( _settings );
_settings = new Dictionary<string,string>();
DataAccess da = new DataAccess(); //My DAL
foreach (DataRow row in da.GetSiteSettings().Tables[0].Rows)
{
Settings oSetting = new Settings();
oSetting.SettingsInitFromRow(row);
}

HttpRuntime.Cache.Insert("SiteSettings",
_settings,
null,

• I like the idea. I really do. A few comments. One, it looks like in LoadSettings() it's not checking for cache, and pulling from this rather than "yet another DB call" times 5. Or is this being checked here if( _settings == null ){ _seetings = LoadSettings(); }? As far as TryGetValue vs Contains, first off, I was not aware of it but I like it, a lot. Second I guess I just really like one liners. Never the less, I'll give it a whirl. – Tim Meers Aug 6 '11 at 2:59
• So I changed LoadSettings to actually load the settings each time it is called. We only call it once however when the cahced settings are asked for the first time. After that _settings will not be null and we will just return that. You can do that part however you like of course, it's semantically the same as your version. – Ed S. Aug 6 '11 at 4:21