using System; using System.Collections.Generic; using System.Configuration; using System.Web; using System.Web.Caching; using System.Web.Configuration; namespace VHelms.Web { /// /// Can be used to open another web.config file with caching. /// public class MultiWebConfigManager { private static readonly Dictionary Configs = new Dictionary(); #region Indexers /// /// Gets the from the specified path. /// /// public Configuration this[string configPath] { get { return GetConfig(configPath); } } /// /// Gets the from the specified configPath web.config's appSettings key. /// /// public string this[string configPath, string key] { get { return GetConfig(configPath).AppSettings.Settings[key].Value; } } #endregion Indexers #region Public methods /// /// Gets the web.config file located at the specified path. /// /// /// public static Configuration GetConfig(string configPath) { //attempt to load from dictionary if (Configs.ContainsKey(configPath)) return Configs[configPath]; //attempt to load from disk and add to dictionary Configuration config = LoadConfig(configPath); if (config != null) { Configs.Add(configPath, config); return config; } //doesn't exist, error out throw new ConfigurationErrorsException("A web configuration file could not be found at " + configPath); } #endregion Public methods #region Private methods /// /// Loads the web.config from the given path. If a web.config is found it is stored in cache and monitored for chagnes. /// /// The directory where the web.config is located. /// private static Configuration LoadConfig(string configPath) { Configuration config = WebConfigurationManager.OpenWebConfiguration(configPath); //If the config was loaded we want to monitor it for changes (use cache) //I decided to not store the config in the cache itself for performance (boxing/unboxing from cache) // and complexity (dictionary in cache, only wanting to expire a single config vs. // the entire dictionary on invalidation). string configFilePath = HttpContext.Current.Server.MapPath(configPath + "\\web.config"); HttpContext.Current.Cache.Add("config_" + configPath, configPath, new CacheDependency(configFilePath), Cache.NoAbsoluteExpiration, new TimeSpan(0, 10, 0), CacheItemPriority.Normal, ConfigCacheRemoved); return config; } /// /// Called when a configuration cache item is invalidated. /// /// The name of the cache item. /// The value of the cache item. /// The reason the cache was invalidated. private static void ConfigCacheRemoved(string name, object value, CacheItemRemovedReason reason) { //if the item exists in the dictionary, remove it because it changed if (Configs.ContainsKey(value.ToString())) Configs.Remove(value.ToString()); } #endregion Private methods } }