using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Xml.Linq;
using CTA.Rules.Config;
namespace CTA.Rules.Common.WebConfigManagement
{
///
/// Consumers can use this class to load a Web.config into memory specify its representation based on need.
/// For accessing more well-defined Web.config properties (e.g. connection strings), it can be loaded as a
/// Configuration object. For more flexible navigation, it can be loaded as an XDocument with additional
/// helper functions.
///
public class WebConfigManager
{
private static ConcurrentDictionary _configurationCache = new ConcurrentDictionary();
private static ConcurrentDictionary _xDocumentCache = new ConcurrentDictionary();
private delegate object ConfigLoadingDelegate(string configFile);
// Currently unused
[ExcludeFromCodeCoverage]
public static Configuration LoadWebConfigAsConfiguration(string projectDir)
{
var config = LoadWebConfig(projectDir, webConfigFile =>
{
if (_configurationCache.TryGetValue(webConfigFile, out var cached))
{
return cached;
}
var fileMap = new ExeConfigurationFileMap {ExeConfigFilename = webConfigFile};
var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
_configurationCache[webConfigFile] = configuration;
return _configurationCache[webConfigFile];
}) as Configuration;
return config;
}
public static WebConfigXDocument LoadWebConfigAsXDocument(string projectDir)
{
var config = LoadWebConfig(projectDir, webConfigFile =>
{
if (_xDocumentCache.TryGetValue(webConfigFile, out var cached))
{
return cached;
}
var xDocument = XDocument.Load(webConfigFile);
_xDocumentCache[webConfigFile] = xDocument;
return _xDocumentCache[webConfigFile];
}) as XDocument;
return new WebConfigXDocument(config);
}
public static WebConfigXDocument LoadAppConfigAsXDocument(string projectDir)
{
var config = LoadAppConfig(projectDir, appConfigFile =>
{
if (_xDocumentCache.TryGetValue(appConfigFile, out var cached))
{
return cached;
}
var xDocument = XDocument.Load(appConfigFile);
_xDocumentCache[appConfigFile] = xDocument;
return _xDocumentCache[appConfigFile];
}) as XDocument;
return new WebConfigXDocument(config);
}
public static void ClearCache()
{
_configurationCache = new ConcurrentDictionary();
_xDocumentCache = new ConcurrentDictionary();
}
private static object LoadWebConfig(string projectDir, ConfigLoadingDelegate configLoadingDelegate)
{
string webConfigFile = Path.Combine(projectDir, Constants.WebConfig);
if (File.Exists(webConfigFile))
{
try
{
return configLoadingDelegate.Invoke(webConfigFile);
}
catch (Exception ex)
{
LogHelper.LogError(ex, string.Format("Error processing web.config file {0}", webConfigFile));
}
}
return null;
}
private static object LoadAppConfig(string projectDir, ConfigLoadingDelegate configLoadingDelegate)
{
string appConfigFile = Path.Combine(projectDir, Constants.AppConfig);
if(File.Exists(appConfigFile))
{
try
{
return configLoadingDelegate.Invoke(appConfigFile);
}
catch (Exception ex)
{
LogHelper.LogError(ex, string.Format("Error processing App.config file {0}", appConfigFile));
}
}
return null;
}
}
}