Click here to Skip to main content
15,886,362 members
Articles / Web Development / HTML

A WPF Template solution using MVVM and Castle Windsor

Rate me:
Please Sign up or sign in to vote.
4.78/5 (11 votes)
18 Nov 2013CPOL5 min read 34.8K   1.2K   19  
A WPF application base solution using Castle Windsor and commonly used utilities.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using System.Reflection;
using System.Configuration;
using CommonData;
using Interfaces;

namespace CommonUtilities
{
    public class CommonConfig : IConfig
    {
        #region Private members

        /// <summary>
        /// The _config file
        /// </summary>
        private string _configFile;

        /// <summary>
        /// The settings dictionay
        /// </summary>
        private readonly Dictionary<string, string> _allSettings = new Dictionary<string, string>();

        #endregion

        #region Constructor

        /// <summary>
        /// Prevents a default instance of the <see cref="CommonConfig"/> class from being created.
        /// </summary>
        public CommonConfig() 
        {
            UseLocalConfig = true;
        }

        #endregion


        #region Properties
        
        /// <summary>
        /// The current Installed application on the machine
        /// </summary>
        public string InstallationPath { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether [use local configuration].
        /// </summary>
        /// <value>
        /// <c>true</c> if [use local configuration]; otherwise, <c>false</c>.
        /// </value>
        public bool UseLocalConfig { get; set; }

        /// <summary>
        /// Defines the configuration file.
        /// </summary>
        /// <returns></returns>
        private string DefineConfigFile()
        {
            string s = ConfigurationManager.AppSettings["LocalConfig"];

            if (UseLocalConfig ||
                (null != s && string.Equals(bool.TrueString, s, StringComparison.InvariantCultureIgnoreCase)))
            {
                Assembly asm = Assembly.GetExecutingAssembly();
                string asmFileName = AssemblyHelper.AssemblyFileName(asm);
                // ReSharper disable AssignNullToNotNullAttribute
                string confFileName = Path.Combine(Path.GetDirectoryName(asmFileName), AppConstants.GlobalConfigFileName);
                // ReSharper restore AssignNullToNotNullAttribute
                if (File.Exists(confFileName))
                {
                    return confFileName;
                }
            }

            return Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "ST"), AppConstants.GlobalConfigFileName);
        }

        /// <summary>
        /// The global config file path
        /// </summary>
        public string GlobalConfigFile
        {
            get
            {
                if (_configFile == null)
                {
                    _configFile = DefineConfigFile();
                }
                return (_configFile);
            }
        }

        #endregion

        #region XML Helper methods

        /// <summary>
        /// Gets the XML document.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="key">The key.</param>
        /// <param name="appSettingValueNode">The application setting value node.</param>
        /// <returns></returns>
        private XmlDocument GetXmlDoc(string fileName, string key, out XmlNode appSettingValueNode)
        {
            appSettingValueNode = null;
            if (!File.Exists(fileName))
                return null;

            // create XML reader
            var xmlDoc = new XmlDocument();

            using (XmlReader xmlReader = new XmlTextReader(fileName))
            {
                // load file
                xmlDoc.Load(xmlReader);
            }

            // parse file
            //Using regex to select the Server Url and then changes the xml file accordingly
            var appSettingNode = xmlDoc.SelectSingleNode("/configuration/appSettings/add[@key = '{0}']".Fmt(key));
            if (appSettingNode == null || appSettingNode.Attributes == null)
                return xmlDoc;

            appSettingValueNode = appSettingNode.Attributes.GetNamedItem("value");

            return xmlDoc;
        }
        
        /// <summary>
        /// Add new element to XML file
        /// </summary>
        /// <param name="xmlDoc"></param>
        /// <param name="elementName"></param>
        /// <param name="tagName"></param>
        private XmlNode GetOrCreateXmlElement(XmlDocument xmlDoc, string elementName, string tagName)
        {
            if (xmlDoc == null || elementName.IsNullOrEmpty() || tagName.IsNullOrEmpty())
                return null;

            // first try find existing element
            var mainTag = xmlDoc.GetElementsByTagName(tagName).Cast<XmlNode>().FirstOrDefault();
            if (mainTag == null)
            {
                // add it in the root of the doc
                var root = xmlDoc.FirstChild ?? xmlDoc.AppendChild(xmlDoc.CreateNode(XmlNodeType.Element, "configuration", ""));
                mainTag = root.AppendChild(xmlDoc.CreateNode(XmlNodeType.Element, tagName, ""));
            }
            var addNodes = mainTag.ChildNodes.Cast<XmlNode>().Where(n => n.Name == "add");
            var myNode = addNodes.Where(n => n.Attributes["key"].Value == elementName).FirstOrDefault();
            if (myNode == null)
            {
                myNode = xmlDoc.CreateNode(XmlNodeType.Element, "add", "");
                var xmlKey = xmlDoc.CreateAttribute("key");
                var xmlValue = xmlDoc.CreateAttribute("value");
                xmlKey.Value = elementName;

                myNode.Attributes.Append(xmlKey);
                myNode.Attributes.Append(xmlValue);
                mainTag.InsertAfter(myNode, mainTag.LastChild);
            }
            return myNode;
        }

        /// <summary>
        /// Adds or updates a setting in the specified config file
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void CreateOrUpdateSetting(string fileName, string key, string value)
        {
            XmlNode appSettingValueNode;
            var xmlDoc = GetXmlDoc(fileName, key, out appSettingValueNode);
            if (xmlDoc == null)
                return; // we don't necessarily need to find the app settings value node; we might still need to add it.

            if (appSettingValueNode == null)
            {
                // add vplan element to config file
                var appSettingNode = GetOrCreateXmlElement(xmlDoc, key, "appSettings");
                appSettingValueNode = appSettingNode.Attributes.NullOr(a => a.GetNamedItem("value"));
            }

            var oldValue = appSettingValueNode.Value;

            // save only when changed
            if (string.Compare(oldValue, value, true) == 0)
                return;

            _allSettings[key] = value;

            appSettingValueNode.Value = value;
            try
            {
                xmlDoc.Save(fileName);
            }
            catch (Exception ex)
            {
                //ERROR Message here - LOG
                Log.ErrorMessage("Error Creating or Updating CommonConfig File.", ex);
            }
        }

        /// <summary>
        /// Returns a setting from the config file, or null if setting not found.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string GetSetting(string key)
        {
            string value;
            return _allSettings.TryGetValue(key, out value) ? value : null;
        }

        /// <summary>
        /// Returns a setting from the specified xml file, or null if setting not found.
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string GetSetting(string fileName, string key)
        {
            var cfg = new CommonConfig();
            cfg.LoadFile(fileName);
            string value;
            return cfg._allSettings.TryGetValue(key, out value) ? value : null;
        }

        #endregion

        #region CommonConfig file
        
        /// <summary>
        /// read %FileName%.config
        /// </summary>
        /// <returns>IConfig</returns>
        public void ReadGlobalConfigFile()
        {
            Read(GlobalConfigFile);
        }

       /// <summary>
        /// read %FileName%.config
        /// </summary>
        /// <param name="fileName">file name</param>
        /// <returns>IConfig</returns>
        public void Read(string fileName)
        {
            LoadFile(fileName);
        }

        /// <summary>
        /// Loads the file.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <exception cref="System.Exception"></exception>
        public void LoadFile(string fileName)
        {
            if (!File.Exists(fileName))
                return;

            using (XmlReader xmlReader = new XmlTextReader(fileName))
            {
                try
                {
                    // create XML reader
                    XmlDocument xmlDoc = new XmlDocument();

                    // load file
                    xmlDoc.Load(xmlReader);

                    // parse file
                    XmlNodeList appSettingNodes = xmlDoc.SelectNodes("/configuration/appSettings/add");

                    // loop nodes
                    string key = null;

                    if (appSettingNodes != null)
                    {
                        foreach (XmlNode appSettingNode in appSettingNodes)
                        {
                            var attributes = appSettingNode.Attributes;
                            if (attributes != null) key = attributes.GetNamedItem("key").Value;

                            if (appSettingNode.Attributes == null || key == null)
                                continue;

                            var val = appSettingNode.Attributes.GetNamedItem("value").Value;
                            _allSettings[key] = val;

                            switch (key.ToLower())
                            {
                                case "addparametertest":
                                    break;

                            }
                        }
                    }
                }
                catch (Exception exception)
                {
                    throw new Exception(string.Format("CommonConfig file is corrupted", Environment.NewLine, exception.Message));
                }

                finally
                {
                    xmlReader.Close();
                }
            }
        }


        /// <summary>
        /// Updates the configuration parameter.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="parameter">The parameter.</param>
        /// <param name="value">The value.</param>
        public void UpdateConfigParameter(string fileName, string parameter, string value)
        {
            CreateOrUpdateSetting(fileName, parameter, value);
        }


        #endregion

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Scodix
Israel Israel
Project Manager and Application Developer, in a wide variety of business applications. Particularly interested in client/server and Graphical User Interface design using Visual C#.

Specialties: 13 Y'rs in C#, 10 Y'rs experience in C++ Highly experienced in wide technologies, IT projects, military projects etc'.

Comments and Discussions