2 // System.Web.Configuration.WebConfigurationManager.cs
5 // Lluis Sanchez Gual (lluis@novell.com)
6 // Chris Toshok (toshok@ximian.com)
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
34 using System.Collections;
35 using System.Collections.Specialized;
36 using System.Reflection;
41 using System.Configuration;
42 using System.Configuration.Internal;
43 using _Configuration = System.Configuration.Configuration;
45 namespace System.Web.Configuration {
47 public static class WebConfigurationManager
50 static IInternalConfigConfigurationFactory configFactory;
51 static Hashtable configurations = Hashtable.Synchronized (new Hashtable ());
52 static Hashtable sectionCache = new Hashtable (StringComparer.OrdinalIgnoreCase);
54 const string AppSettingsKey = "WebConfigurationManager.AppSettings";
55 static internal IInternalConfigConfigurationFactory configFactory
58 IInternalConfigConfigurationFactory factory = (IInternalConfigConfigurationFactory)AppDomain.CurrentDomain.GetData("WebConfigurationManager.configFactory");
60 lock (AppDomain.CurrentDomain){
61 object initialized = AppDomain.CurrentDomain.GetData("WebConfigurationManager.configFactory.initialized");
62 if (initialized == null){
63 PropertyInfo prop = typeof(ConfigurationManager).GetProperty("ConfigurationFactory", BindingFlags.Static | BindingFlags.NonPublic);
65 factory = prop.GetValue(null, null) as IInternalConfigConfigurationFactory;
66 configFactory = factory;
71 return factory != null ? factory : configFactory;
74 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configFactory", value);
75 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configFactory.initialized", true);
79 static internal Hashtable configurations
82 Hashtable table = (Hashtable)AppDomain.CurrentDomain.GetData("WebConfigurationManager.configurations");
84 lock (AppDomain.CurrentDomain){
85 object initialized = AppDomain.CurrentDomain.GetData("WebConfigurationManager.configurations.initialized");
86 if (initialized == null){
87 table = Hashtable.Synchronized (new Hashtable (StringComparer.OrdinalIgnoreCase));
88 configurations = table;
92 return table != null ? table : configurations;
96 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations", value);
97 AppDomain.CurrentDomain.SetData("WebConfigurationManager.configurations.initialized", true);
101 static Hashtable sectionCache
105 Hashtable sectionCache = (Hashtable) AppDomain.CurrentDomain.GetData ("sectionCache");
106 if (sectionCache == null) {
107 sectionCache = new Hashtable (StringComparer.OrdinalIgnoreCase);
108 AppDomain.CurrentDomain.SetData ("sectionCache", sectionCache);
114 AppDomain.CurrentDomain.SetData ("sectionCache", value);
119 static ArrayList extra_assemblies = null;
120 static internal ArrayList ExtraAssemblies {
122 if (extra_assemblies == null)
123 extra_assemblies = new ArrayList();
124 return extra_assemblies;
128 static bool hasConfigErrors = false;
129 static object hasConfigErrorsLock = new object ();
130 static internal bool HasConfigErrors {
132 lock (hasConfigErrorsLock) {
133 return hasConfigErrors;
138 static WebConfigurationManager ()
140 PropertyInfo prop = typeof(ConfigurationManager).GetProperty ("ConfigurationFactory", BindingFlags.Static | BindingFlags.NonPublic);
142 configFactory = prop.GetValue (null, null) as IInternalConfigConfigurationFactory;
145 public static _Configuration OpenMachineConfiguration ()
147 return ConfigurationManager.OpenMachineConfiguration ();
150 [MonoLimitation ("locationSubPath is not handled")]
151 public static _Configuration OpenMachineConfiguration (string locationSubPath)
153 return OpenMachineConfiguration ();
156 [MonoLimitation("Mono does not support remote configuration")]
157 public static _Configuration OpenMachineConfiguration (string locationSubPath,
161 return OpenMachineConfiguration (locationSubPath);
163 throw new NotSupportedException ("Mono doesn't support remote configuration");
166 [MonoLimitation("Mono does not support remote configuration")]
167 public static _Configuration OpenMachineConfiguration (string locationSubPath,
172 return OpenMachineConfiguration (locationSubPath);
173 throw new NotSupportedException ("Mono doesn't support remote configuration");
176 [MonoLimitation("Mono does not support remote configuration")]
177 public static _Configuration OpenMachineConfiguration (string locationSubPath,
183 return OpenMachineConfiguration (locationSubPath);
184 throw new NotSupportedException ("Mono doesn't support remote configuration");
187 public static _Configuration OpenWebConfiguration (string path)
189 return OpenWebConfiguration (path, null, null, null, null, null);
192 public static _Configuration OpenWebConfiguration (string path, string site)
194 return OpenWebConfiguration (path, site, null, null, null, null);
197 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath)
199 return OpenWebConfiguration (path, site, locationSubPath, null, null, null);
202 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server)
204 return OpenWebConfiguration (path, site, locationSubPath, server, null, null);
207 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, IntPtr userToken)
209 return OpenWebConfiguration (path, site, locationSubPath, server, null, null);
212 public static _Configuration OpenWebConfiguration (string path, string site, string locationSubPath, string server, string userName, string password)
214 if (path == null || path.Length == 0)
219 conf = (_Configuration) configurations [path];
222 conf = ConfigurationFactory.Create (typeof (WebConfigurationHost), null, path, site, locationSubPath, server, userName, password);
223 configurations [path] = conf;
224 } catch (Exception ex) {
225 lock (hasConfigErrorsLock) {
226 hasConfigErrors = true;
234 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path)
236 return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path);
239 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path, string site)
241 return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path, site);
244 public static _Configuration OpenMappedWebConfiguration (WebConfigurationFileMap fileMap, string path, string site, string locationSubPath)
246 return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap, path, site, locationSubPath);
249 public static _Configuration OpenMappedMachineConfiguration (ConfigurationFileMap fileMap)
251 return ConfigurationFactory.Create (typeof(WebConfigurationHost), fileMap);
254 public static _Configuration OpenMappedMachineConfiguration (ConfigurationFileMap fileMap,
255 string locationSubPath)
257 return OpenMappedMachineConfiguration (fileMap);
260 internal static object SafeGetSection (string sectionName, Type configSectionType)
263 return GetSection (sectionName);
264 } catch (Exception) {
265 if (configSectionType != null)
266 return Activator.CreateInstance (configSectionType);
271 internal static object SafeGetSection (string sectionName, string path, Type configSectionType)
274 return GetSection (sectionName, path);
275 } catch (Exception) {
276 if (configSectionType != null)
277 return Activator.CreateInstance (configSectionType);
282 public static object GetSection (string sectionName)
284 return GetSection (sectionName, GetCurrentPath (HttpContext.Current));
287 public static object GetSection (string sectionName, string path)
289 object cachedSection = sectionCache [GetSectionCacheKey (sectionName, path)];
290 if (cachedSection != null)
291 return cachedSection;
293 _Configuration c = OpenWebConfiguration (path);
294 ConfigurationSection section = c.GetSection (sectionName);
300 object value = get_runtime_object.Invoke (section, new object [0]);
301 if (String.CompareOrdinal ("appSettings", sectionName) == 0) {
302 NameValueCollection collection;
303 collection = new KeyValueMergedCollection (HttpContext.Current, (NameValueCollection) value);
307 AddSectionToCache (GetSectionCacheKey (sectionName, path), value);
311 object value = SettingsMappingManager.MapSection (get_runtime_object.Invoke (section, new object [0]));
315 AddSectionToCache (GetSectionCacheKey (sectionName, path), value);
320 static string GetCurrentPath (HttpContext ctx)
322 return (ctx != null && ctx.Request != null) ? ctx.Request.Path : HttpRuntime.AppDomainAppVirtualPath;
325 internal static void RemoveConfigurationFromCache (HttpContext ctx)
327 configurations.Remove (GetCurrentPath (ctx));
330 readonly static MethodInfo get_runtime_object = typeof (ConfigurationSection).GetMethod ("GetRuntimeObject", BindingFlags.NonPublic | BindingFlags.Instance);
332 public static object GetWebApplicationSection (string sectionName)
334 string path = (HttpContext.Current == null
335 || HttpContext.Current.Request == null
336 || HttpContext.Current.Request.ApplicationPath == null
337 || HttpContext.Current.Request.ApplicationPath == "") ?
338 String.Empty : HttpContext.Current.Request.ApplicationPath;
340 return GetSection (sectionName, path);
343 public static NameValueCollection AppSettings {
344 get { return ConfigurationManager.AppSettings; }
347 public static ConnectionStringSettingsCollection ConnectionStrings {
348 get { return ConfigurationManager.ConnectionStrings; }
351 internal static IInternalConfigConfigurationFactory ConfigurationFactory {
352 get { return configFactory; }
355 static void AddSectionToCache (string key, object section)
357 if (sectionCache [key] != null)
360 Hashtable tmpTable = (Hashtable) sectionCache.Clone ();
361 if (tmpTable.Contains (key))
364 tmpTable.Add (key, section);
365 sectionCache = tmpTable;
368 static string GetSectionCacheKey (string sectionName, string path)
370 return string.Concat (path, "/", sectionName);
374 #region stuff copied from WebConfigurationSettings
376 static internal IConfigurationSystem oldConfig {
378 return (IConfigurationSystem)AppDomain.CurrentDomain.GetData("WebConfigurationManager.oldConfig");
381 AppDomain.CurrentDomain.SetData("WebConfigurationManager.oldConfig", value);
385 static private Web20DefaultConfig config {
387 return (Web20DefaultConfig) AppDomain.CurrentDomain.GetData ("Web20DefaultConfig.config");
390 AppDomain.CurrentDomain.SetData ("Web20DefaultConfig.config", value);
394 static private IInternalConfigSystem configSystem {
396 return (IInternalConfigSystem) AppDomain.CurrentDomain.GetData ("IInternalConfigSystem.configSystem");
399 AppDomain.CurrentDomain.SetData ("IInternalConfigSystem.configSystem", value);
403 static internal IConfigurationSystem oldConfig;
404 static Web20DefaultConfig config;
405 //static IInternalConfigSystem configSystem;
407 const BindingFlags privStatic = BindingFlags.NonPublic | BindingFlags.Static;
408 static readonly object lockobj = new object ();
410 internal static void Init ()
416 /* deal with the ConfigurationSettings stuff */
418 Web20DefaultConfig settings = Web20DefaultConfig.GetInstance ();
419 Type t = typeof (ConfigurationSettings);
420 MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
423 if (changeConfig == null)
424 throw new ConfigurationException ("Cannot find method CCS");
426 object [] args = new object [] {settings};
427 oldConfig = (IConfigurationSystem)changeConfig.Invoke (null, args);
433 /* deal with the ConfigurationManager stuff */
435 HttpConfigurationSystem system = new HttpConfigurationSystem ();
436 Type t = typeof (ConfigurationManager);
437 MethodInfo changeConfig = t.GetMethod ("ChangeConfigurationSystem",
440 if (changeConfig == null)
441 throw new ConfigurationException ("Cannot find method CCS");
443 object [] args = new object [] {system};
444 changeConfig.Invoke (null, args);
445 //configSystem = system;
451 class Web20DefaultConfig : IConfigurationSystem
454 static private Web20DefaultConfig instance {
456 Web20DefaultConfig val = (Web20DefaultConfig)AppDomain.CurrentDomain.GetData("Web20DefaultConfig.instance");
458 val = new Web20DefaultConfig();
459 AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", val);
464 AppDomain.CurrentDomain.SetData("Web20DefaultConfig.instance", value);
468 static Web20DefaultConfig instance;
471 static Web20DefaultConfig ()
473 instance = new Web20DefaultConfig ();
476 public static Web20DefaultConfig GetInstance ()
481 public object GetConfig (string sectionName)
483 object o = WebConfigurationManager.GetWebApplicationSection (sectionName);
485 if (o == null || o is IgnoreSection) {
486 /* this can happen when the section
487 * handler doesn't subclass from
488 * ConfigurationSection. let's be
489 * nice and try to load it using the
490 * 1.x style routines in case there's
491 * a 1.x section handler registered
494 object o1 = WebConfigurationManager.oldConfig.GetConfig (sectionName);
504 // nothing. We need a context.