onsen code monkey

個人的な日記とプログラミング備忘録です

【C#】シングルトンサンプル

using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Diagnostics;
using System.Collections.Generic;
using System.Threading;
using JWS.Com.Model;

namespace JWS.CWS.FW.App
{
    /// <summary>
    /// キー値クラス
    /// 内部クラス
    /// </summary>
    public class KeyValue
    {
        /// <summary>
        /// キーと値を指定してオブジェクトを生成する。
        /// </summary>
        /// <param name="key">キー</param>
        /// <param name="value"></param>
        public KeyValue(string key, string value)
        {
            this._key = key;
            this._value = value;
        }

        /// <summary>
        /// キー
        /// </summary>
        private string _key;

        /// <summary>
        /// キーを取得する。
        /// </summary>
        /// <returns>キー</returns>
        public string Getkey()
        {
            return _key;
        }

        /// <summary>
        /// 値
        /// </summary>
        private string _value;

        /// <summary>
        /// 値を取得する
        /// </summary>
        /// <returns></returns>
        public string GetValue()
        {
            return _value;
        }

        /// <summary>
        /// 文字列に変換する
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return string.Format("key = {0}, value = {1}", _key, _value);
        }
    }

    /// <summary>
    /// 環境定義ファイル
    /// </summary>
    public class EnvironmentFile
    {
        /// <summary>
        ///  環境変数
        /// </summary>
        private string _EnvFile = ComConst.stEnvDir + "\\COMENVFILE.ini";

        /// <summary>
        /// 最終更新時刻(ms)
        /// </summary>
        private DateTime _LastUpdateTime;

        /// <summary>
        /// ロック
        /// </summary>
        private ReaderWriterLock rwLock = new ReaderWriterLock();

        /// <summary>
        /// シングルトン・インスタンス
        /// </summary>
        private static EnvironmentFile _Instance;

        /// <summary>
        /// インスタンス取得
        /// </summary>
        /// <returns>シングルトン・インスタンス</returns>
        public static EnvironmentFile Instance
        {
            get
            {
                if (EnvironmentFile._Instance == null)
                {
                    EnvironmentFile instance = new EnvironmentFile();
                    instance.Init();
                    EnvironmentFile._Instance = instance;
                }
                return EnvironmentFile._Instance;
            }
        }

        /// <summary>
        /// 初期化処理
        /// </summary>
        public void Init()
        {
            try
            {
                // 環境ファイルの有無を確認
                IsolatedStorageFile storageFile = JWS.CWS.Storage.IsolatedStorage.GetUserStore();
                if (!storageFile.FileExists(_EnvFile))
                {
                    throw new IOException();
                }
                this._LastUpdateTime = storageFile.GetLastWriteTime(_EnvFile).DateTime;

                // 読み込み
                Load();

            }
            finally
            {

            }
        }

        /// <summary>
        /// データをクリアする
        /// </summary>
        public void Clear()
        {
            try
            {
                rwLock.AcquireWriterLock(Timeout.Infinite);

                if (_Items != null)
                {
                    _Items.Clear();
                }
                else
                {
                    _Items = new Dictionary<string, Dictionary<string, string>>();
                }
            }
            finally
            {
                rwLock.ReleaseWriterLock();
            }
        }

        /// <summary>
        /// ファイルの更新を確認する
        /// </summary>
        /// <returns>更新されている場合はtrue</returns>
        protected bool IsUpdate()
        {
            IsolatedStorageFile storageFile = JWS.CWS.Storage.IsolatedStorage.GetUserStore();
            if (!storageFile.FileExists(_EnvFile))
            {
                return false;
            }

            DateTime lastWriteTime = storageFile.GetLastWriteTime(_EnvFile).DateTime;
            return (this._LastUpdateTime < lastWriteTime);
        }

        /// <summary>
        /// アイテム
        /// </summary>
        protected Dictionary<string, Dictionary<string, string>> _Items;

        /// <summary>
        /// 環境作成
        /// </summary>
        protected void Load()
        {
            try
            {
                Clear();
                rwLock.AcquireWriterLock(Timeout.Infinite);

                // 分離ストレージより定義ファイルの読み出し
                using (IsolatedStorageFile file = JWS.CWS.Storage.IsolatedStorage.GetUserStore())
                {
                    // ストリーム取得
                    using (IsolatedStorageFileStream stream
                        = new IsolatedStorageFileStream(_EnvFile, FileMode.Open, file))
                    {
                        // 読み込み
                        using (StreamReader reader = new StreamReader(stream))
                        {
                            string stLine;
                            string line;
                            string section = null;
                            string currentSection = null;
                            KeyValue keyValue;
                            while ((stLine = reader.ReadLine()) != null)
                            {
                                line = stLine.Trim();
                                if (line.Length == 0)
                                {
                                    // 空行は無視
                                    continue;
                                }
                                if (IsComment(line))
                                {
                                    // コメント行は無視
                                    continue;
                                }
                                // セクション解析
                                section = ParseSection(line);
                                if (section != null)
                                {
                                    // セクションを更新
                                    currentSection = section;
                                    continue;
                                }
                                // キー解析
                                keyValue = ParseKeyValue(line);
                                if (keyValue != null)
                                {
                                    AddItem(currentSection, keyValue);
                                }
                            }
                        }
                    }
                    this._LastUpdateTime = file.GetLastWriteTime(_EnvFile).DateTime;
                }
            }
            finally
            {
                rwLock.ReleaseWriterLock();
            }
        }

        /// <summary>
        /// コメント判定
        /// </summary>
        /// <param name="line"></param>
        /// <returns>コメントであればtrue</returns>
        protected bool IsComment(string line)
        {
            bool result = false;
            if (line.StartsWith("#") || line.StartsWith("\\"))
            {
                result = true;
            }
            return result;
        }

        /// <summary>
        /// セクション解析
        /// </summary>
        /// <param name="line"></param>
        /// <returns>セクション</returns>
        protected string ParseSection(string line)
        {
            string section = null;
            if (line.Length > 2 && line.StartsWith("[") && line.EndsWith("]"))
            {
                section = line.Substring(1, line.Length - 2);
            }
            return section;
        }

        /// <summary>
        /// キー値解析
        /// </summary>
        /// <param name="line"></param>
        /// <returns>KeyValue</returns>
        protected KeyValue ParseKeyValue(string line)
        {
            int index = line.IndexOf("=");
            KeyValue result = null;
            if (index >= 0)
            {
                string key = line.Substring(0, index);
                string value = line.Substring(index + 1);
                if (key != null)
                {
                    result = new KeyValue(key, value);
                }
            }
            return result;
        }

        /// <summary>
        /// アイテムを追加する
        /// </summary>
        /// <param name="section">セクション</param>
        /// <param name="keyvalue">KeyValue</param>
        protected void AddItem(string section, KeyValue item)
        {
            try
            {
                rwLock.AcquireWriterLock(Timeout.Infinite);
                if (section == null)
                {
                    section = "";
                }
                Dictionary<string, string> keyValues = null;
                if (!this._Items.TryGetValue(section, out keyValues))
                {
                    keyValues = new Dictionary<string, string>();
                    keyValues.Add(item.Getkey().Trim(), item.GetValue().Trim());

                    this._Items.Add(section, keyValues);
                }
                keyValues[item.Getkey().Trim()] = item.GetValue().Trim();
            }
            finally
            {
                rwLock.ReleaseWriterLock();
            }
        }

        /// <summary>
        /// 環境設定ファイルの更新を確認する
        /// </summary>
        protected void ConfirmUpdate()
        {
            if (IsUpdate())
            {
                Load();
            }
        }

        /// <summary>
        /// プロパティを string 型で取得する
        /// </summary>
        /// <param name="section">セクション</param>
        /// <param name="key">キー</param>
        /// <param name="defaultValue">デフォルト値</param>
        /// <returns>プロパティを返却する。設定がない場合は、デフォルト値を返却する。</returns>
        public string GetString(string section, string key, string defaultValue)
        {
            try
            {
                ConfirmUpdate();
                rwLock.AcquireReaderLock(Timeout.Infinite);
                string value = defaultValue;
                do
                {
                    if (_Items == null)
                    {
                        break;
                    }
                    Dictionary<string, string> keyValues = null;
                    if (!this._Items.TryGetValue(section, out keyValues))
                    {
                        break;
                    }

                    if (keyValues.ContainsKey(key))
                    {
                        value = keyValues[key];
                    }
                } while (false); // 1回のみループ
                return value;
            }
            finally
            {
                rwLock.ReleaseReaderLock();
            }
        }

        public string GetString(string section, string key)
        {
            return GetString(section, key, null);
        }

        /// <summary>
        /// プロパティを int 型で取得する
        /// </summary>
        /// <param name="section">セクション</param>
        /// <param name="key">キー</param>
        /// <param name="defaultValue">デフォルト値</param>
        /// <returns>プロパティを返却する。設定がない場合は、デフォルト値を返却する。</returns>
        public Nullable<int> GetInt(string section, string key, Nullable<int> defaultValue)
        {
            try
            {
                Nullable<int> value = null;
                string valueString = GetString(section, key, null);
                if (valueString == null)
                {
                    value = defaultValue;
                }
                else
                {
                    value = int.Parse(valueString);
                }
                return value;
            }
            catch (FormatException)
            {
                return defaultValue;
            }
            finally
            {

            }
        }

        public Nullable<int> GetInt(string section, string key)
        {
            return GetInt(section, key, null);
        }

        /// <summary>
        /// プロパティを bool 型で取得する
        /// </summary>
        /// <param name="section">セクション</param>
        /// <param name="key">キー</param>
        /// <param name="defaultValue">デフォルト値</param>
        /// <returns>プロパティを返却する。設定がない場合は、デフォルト値を返却する。</returns>
        public Nullable<bool> GetBoolean(string section, string key, Nullable<bool> defaultValue)
        {
            try
            {
                Nullable<bool> value = null;
                string valueString = GetString(section, key, null);
                if (valueString == null)
                {
                    return defaultValue;
                }
                valueString = valueString.ToLower();
                if ("true".Equals(valueString))
                {
                    value = true;
                }
                else if ("false".Equals(valueString) || "0".Equals(valueString))
                {
                    value = false;
                }
                else
                {
                    if (int.Parse(valueString) > 0)
                    {
                        value = true;
                    }
                    else
                    {
                        value = defaultValue;
                    }
                }
                return value;
            }
            catch (FormatException)
            {
                return defaultValue;
            }
            finally
            {

            }
        }

        public Nullable<bool> GetBoolean(string section, string key)
        {
            return GetBoolean(section, key, null);
        }

        /// <summary>
        /// プロパティを long 型で取得する
        /// </summary>
        /// <param name="section">セクション</param>
        /// <param name="key">キー</param>
        /// <param name="defaultValue">デフォルト値</param>
        /// <returns>プロパティを返却する。設定がない場合は、デフォルト値を返却する。</returns>
        public Nullable<long> GetLong(string section, string key, Nullable<long> defaultValue)
        {
            try
            {
                Nullable<long> value = null;
                string valueString = GetString(section, key, null);
                if (valueString == null)
                {
                    value = defaultValue;
                }
                else
                {
                    value = long.Parse(valueString);
                }
                return value;
            }
            catch (FormatException)
            {
                return defaultValue;
            }
            finally
            {

            }
        }

        public Nullable<long> GetLong(string section, string key)
        {
            return GetLong(section, key, null);
        }

        /// <summary>
        /// プロパティを float 型で取得する
        /// </summary>
        /// <param name="section">セクション</param>
        /// <param name="key">キー</param>
        /// <param name="defaultValue">デフォルト値</param>
        /// <returns>プロパティを返却する。設定がない場合は、デフォルト値を返却する。</returns>
        public Nullable<float> GetFloat(string section, string key, Nullable<float> defaultValue)
        {
            try
            {
                Nullable<float> value = null;
                String valueString = GetString(section, key, null);
                if (valueString == null)
                {
                    value = defaultValue;
                }
                else
                {
                    value = float.Parse(valueString);
                }
                return value;
            }
            catch (FormatException)
            {
                return defaultValue;
            }
            finally
            {

            }
        }

        public Nullable<float> GetFloat(string section, string key)
        {
            return GetFloat(section, key, null);
        }

        /// <summary>
        /// プロパティを double 型で取得する
        /// </summary>
        /// <param name="section">セクション</param>
        /// <param name="key">キー</param>
        /// <param name="defaultValue">デフォルト値</param>
        /// <returns>プロパティを返却する。設定がない場合は、デフォルト値を返却する。</returns>
        public Nullable<double> GetDouble(string section, string key, Nullable<double> defaultValue)
        {
            try
            {
                Nullable<double> value = null;
                string valueString = GetString(section, key, null);
                if (valueString == null)
                {
                    value = defaultValue;
                }
                else
                {
                    value = double.Parse(valueString);
                }
                return value;
            }
            catch (FormatException)
            {
                return defaultValue;
            }
            finally
            {

            }
        }

        public Nullable<double> GetDouble(string section, string key)
        {
            return GetDouble(section, key, null);
        }
    }
}