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
}
}