3
\$\begingroup\$

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)
    {
        return LoadSettings().Contains(settingName) ? Convert.ToString(LoadSettings()[settingName]) : defaultValue;
    }

    /// <summary>
    /// Returns the selected setting value from cache.
    /// If cache is null then rebuild the cache.
    /// </summary>
    /// <returns></returns>
    public static Hashtable LoadSettings()
    {
        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);
                h.Add(oSetting.Name, oSetting.Value);
            }

            HttpRuntime.Cache.Insert("SiteSettings", 
                                    h, 
                                    null, 
                                    DateTime.Now.AddMinutes(120), 
                                    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?

\$\endgroup\$
4
\$\begingroup\$

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 )
        {
            _settings = LoadSettings();
        }       

        return _settings;
    }
}

private static Dictionary<string, string> LoadSettings()
{
    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);
        _settings.Add(oSetting.Name, oSetting.Value);
    }

    HttpRuntime.Cache.Insert("SiteSettings", 
                             _settings, 
                             null, 
                             DateTime.Now.AddMinutes(120), 
                             Cache.NoSlidingExpiration);        

    return _settings;
}
\$\endgroup\$
6
  • \$\begingroup\$ 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. \$\endgroup\$ – Tim Meers Aug 6 '11 at 2:59
  • \$\begingroup\$ 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. \$\endgroup\$ – Ed S. Aug 6 '11 at 4:21
  • \$\begingroup\$ Wouldnt this "foreach (DataRow row in da.GetSiteSettings().Tables[0].Rows)" result in a NullReferenceException if the site had no settings? Just a heads up \$\endgroup\$ – Mattias Aug 7 '11 at 9:55
  • \$\begingroup\$ @Mattias, this table by default will always have at least one item in it that is added as the DB is created. So while it is something to watch, this is static data so it's sort of a non-issue. \$\endgroup\$ – Tim Meers Aug 7 '11 at 18:12
  • 1
    \$\begingroup\$ Glad I could help, cheers. \$\endgroup\$ – Ed S. Aug 7 '11 at 20:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.