Settings class for web app I needed to write a settings class for my web app; ideally this class should read its settings from a file (and be able to save them back to the file), and have only 1 instance per application - all threads read the same object, so that the settings only need to be loaded from the file when the app runs for the first time.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;
using System.Security.Cryptography;
using System.Configuration;
using System.Xml.Serialization;
using System.Web.Caching;
using System.IO;

namespace Secure_Password_Repository.Settings
{
    [Serializable]
    public sealed partial class AppSettings
    {
    private static readonly XmlSerializer serial = new XmlSerializer(typeof(AppSettings));
    private static AppSettings instance;
    private static Object thisLock = new Object();

    private static void serializeToDisk(string key, CacheItemUpdateReason reason, out Object expensiveObject, out CacheDependency dependency, out DateTime absoluteExpiration, out TimeSpan slidingExpiration)
    {

        string filename = HttpContext.Current.Server.MapPath("settings.xml");

        expensiveObject = instance;
        dependency = new CacheDependency(filename);
        absoluteExpiration = Cache.NoAbsoluteExpiration;
        slidingExpiration = Cache.NoSlidingExpiration;

        using (StreamWriter sw = new StreamWriter(filename))
        {
        serial.Serialize(sw, instance);
        }
    }

    public static void Save()
    {
        string filename = HttpContext.Current.Server.MapPath("settings.xml");
        using (StreamWriter sw = new StreamWriter(filename))
        {
        serial.Serialize(sw, instance);
        }
    }

    public static AppSettings Default
    {
        get
        {

        Cache cache = HttpRuntime.Cache;
        string filename = HttpContext.Current.Server.MapPath("settings.xml");

        if (cache[filename] != null) {
            return (AppSettings)cache[filename];
        }

        lock (thisLock)
        {

        if (cache[filename] != null) {
            return (AppSettings)cache[filename];
        }

            using (StreamReader sr = new StreamReader(filename))
            {
            instance = (AppSettings)serial.Deserialize(sr);
            cache.Insert(filename, instance, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration);

            if (instance.EncryptionKeySalt == "")
            {
                //random number generator
                RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();

                //create 20 random bytes for the salt
                byte[] CryptoBytes = new byte[40];
                rngCsp.GetBytes(CryptoBytes);

                rngCsp.Dispose();

                instance.EncryptionKeySalt = Convert.ToBase64String(CryptoBytes);
            }

            return (AppSettings)cache[filename];
            }
        }

        }
    }

    public string LogoImage{ get; set; }

    public string DefaultAccountRole{ get; set; }

    public string SMTPServerAddress{ get; set; }

    public string SMTPServerUsername{ get; set; }

    public string SMTPServerPassword{ get; set; }

    public string EncryptionKeySalt{ get; set; }

    }
}


I'm just curious: is this "good code"? Are there any potential pitfalls I'm not seeing? is there anything I could be doing better?
Small issues:


Personally I'd indent things in between by curly braces
I'd use string.Empty instead of ""
I'd probably put my default public properties before my custom ones


As a higher level question, do you need to use an XML settings file with an explicit lock? Could you not use a custom section in .config file of some kind?