• CSharp: Singleton Pattern in donet core 3


     /// <summary>
        /// 单例模式 Singleton Pattern
        /// geovindu,Geovin Du edit
        /// </summary>
        public class Database
        {
    
            /// <summary>
            /// 
            /// </summary>
            private Database()
            {
            }
    
            /// <summary>
            /// 
            /// </summary>
            public static Database Instance { get; } = new Database();
        }
        /// <summary>
        /// 
        /// </summary>
        public class MyDatabase
        {
    
            /// <summary>
            /// 
            /// </summary>
            private MyDatabase()
            {
                Console.WriteLine("Initializing database");
            }
    
            /// <summary>
            /// 
            /// </summary>
            private static Lazy<MyDatabase> instance =
              new Lazy<MyDatabase>(() => new MyDatabase());
            /// <summary>
            /// 
            /// </summary>
            public static MyDatabase Instance => instance.Value;
        }
        /// <summary>
        /// 
        /// </summary>
        public interface IDatabase
        {
            int GetPopulation(string name);
        }
    
    
        /// <summary>
        /// 
        /// </summary>
        public class SingletonDatabase : IDatabase
        {
    
            /// <summary>
            /// 
            /// </summary>
            private Dictionary<string, int> capitals;
    
            /// <summary>
            /// 
            /// </summary>
            private static int instanceCount;
    
            /// <summary>
            /// 
            /// </summary>
            public static int Count => instanceCount;
            /// <summary>
            /// 
            /// </summary>
            private SingletonDatabase()
            {
                Console.WriteLine("Initializing database");
    
                capitals = File.ReadAllLines(
                  Path.Combine(
                    new FileInfo(typeof(IDatabase).Assembly.Location)
                      .DirectoryName,
                    "capitals.txt")
                  )
                  .Batch(2)
                  .ToDictionary(
                    list => list.ElementAt(0).Trim(),
                    list => int.Parse(list.ElementAt(1)));
            }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="name"></param>
            /// <returns></returns>
            public int GetPopulation(string name)
            {
                return capitals[name];
            }
    
            /// <summary>
            /// laziness + thread safety
            /// </summary>
            private static readonly Lazy<SingletonDatabase> instance
              = new Lazy<SingletonDatabase>(() =>
              {
                  instanceCount++;
                  return new SingletonDatabase();
              });
    
            public static IDatabase Instance => instance.Value;
        }
    
        /// <summary>
        /// 
        /// </summary>
        public class SingletonRecordFinder
        {
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="names"></param>
            /// <returns></returns>
            public int TotalPopulation(IEnumerable<string> names)
            {
                return names.Sum(name => SingletonDatabase.Instance.GetPopulation(name));
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public class ConfigurableRecordFinder
        {
    
            /// <summary>
            /// 
            /// </summary>
            private IDatabase database;
            /// <summary>
            /// 
            /// </summary>
            /// <param name="database"></param>
            public ConfigurableRecordFinder(IDatabase database)
            {
                this.database = database;
            }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="names"></param>
            /// <returns></returns>
            public int GetTotalPopulation(IEnumerable<string> names)
            {
                return names.Sum(name => database.GetPopulation(name));
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public class DummyDatabase : IDatabase
        {
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="name"></param>
            /// <returns></returns>
            public int GetPopulation(string name)
            {
                return new Dictionary<string, int>
                {
                    ["alpha"] = 1,
                    ["beta"] = 2,
                    ["gamma"] = 3
                }[name];
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public class OrdinaryDatabase : IDatabase
        {
    
            /// <summary>
            /// 
            /// </summary>
            private readonly Dictionary<string, int> cities;
            /// <summary>
            /// 
            /// </summary>
            public OrdinaryDatabase()
            {
                Console.WriteLine("Initializing database");
    
                cities = File.ReadAllLines(
                    Path.Combine(
                      new FileInfo(typeof(IDatabase).Assembly.Location)
                        .DirectoryName,
                      "capitals.txt")
                  )
                  .Batch(2)
                  .ToDictionary(
                    list => list.ElementAt(0).Trim(),
                    list => int.Parse(list.ElementAt(1)));
            }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="name"></param>
            /// <returns></returns>
            public int GetPopulation(string name)
            {
                return cities[name];
            }
        }
    

      

     /// <summary>
        /// 单例模式 Singleton Pattern
        /// geovindu,Geovin Du edit
        /// </summary>
        public sealed class Singleton
        {
            #region Singleton implementation using static constructor
            //The following line is discussed in analysis section.
            //private static readonly Singleton Instance = new Singleton();
            private static readonly Singleton Instance;        
    
            private static int TotalInstances;
            /*
             * Private constructor is used to prevent
             * creation of instances with 'new' keyword
             * outside this class.
            */
            /// <summary>
            /// 
            /// </summary>
            private Singleton()
            {
                Console.WriteLine("--Private constructor is called.");
                Console.WriteLine("--Exit now from private constructor.");            
            }
    
            /*
             * A static constructor is used  for the following purposes:
             * 1. To initialize any static data;
             * 2. To perform a specific action only once.
             * 
             * The static constructor will be called automatically before         * 
             * i. You create the first instance; or 
             * ii.You refer to any static members in your code.
             * 
             */
    
            /// <summary>
            /// Here is the static constructor
            /// </summary>
            static Singleton()
            {
                // Printing some messages before you create the instance
                Console.WriteLine("-Static constructor is called.");
                Instance = new Singleton();
                TotalInstances++;
                Console.WriteLine($"-Singleton instance is created.Number of instances:{ TotalInstances}");
                Console.WriteLine("-Exit from static constructor.");            
            }
            /// <summary>
            /// 
            /// </summary>
            public static Singleton GetInstance
            {
                get
                {
                    return Instance;
                }
            }
            
            /* 
             * If you like to use expression-bodied read-only
             * property, you can use the following line (C# v6.0 onwards).
             */
            //public static Singleton GetInstance => Instance;
            #endregion
            /* The following line is used to discuss 
            the drawback of the approach. */
            /// <summary>
            /// 
            /// </summary>
            public static int MyInt = 25;
        }
    

      

    调用:

    Console.WriteLine("***单例模式 Singleton Pattern Demonstration.***\n");
                /*The following line is used to discuss 
                  the drawback of the approach.*/
                //Console.WriteLine($"The value of MyInt is :{Singleton.MyInt}");
                // Private Constructor.So,you cannot use the 'new' keyword.  
                //Singleton s = new Singleton(); // error
               Console.WriteLine("Trying to get a Singleton instance, called firstInstance.");
                Singleton firstInstance = Singleton.GetInstance;
                Console.WriteLine("Trying to get another Singleton instance, called secondInstance.");
                Singleton secondInstance = Singleton.GetInstance;
                if (firstInstance.Equals(secondInstance))
                {
                    Console.WriteLine("The firstInstance and secondInstance are the same.");
                }
                else
                {
                    Console.WriteLine("Different instances exist.");
                }
    
                //
                var rf = new SingletonRecordFinder();
                var names = new[] { "Seoul", "Mexico City" };
                var ci = names[0].ToString();
                int tp = rf.TotalPopulation(names);
                Console.WriteLine(tp);
                var db = new DummyDatabase();
                var rf2 = new ConfigurableRecordFinder(db);
               int t= rf2.GetTotalPopulation(new[] { "alpha", "gamma" }); ;
                Console.WriteLine(t);
                db.GetPopulation("gamma");            
    
                var db2 = SingletonDatabase.Instance;
    
                // works just fine while you're working with a real database.
                var city = "Tokyo";
                Console.WriteLine($"{city} has population {db2.GetPopulation(city)}");
                Console.WriteLine($"{names[0]} has population {db2.GetPopulation(names[0])}");
                Console.Read();
    

      

    输出:

    ***单例模式 Singleton Pattern Demonstration.***
    
    Trying to get a Singleton instance, called firstInstance.
    -Static constructor is called.
    --Private constructor is called.
    --Exit now from private constructor.
    -Singleton instance is created.Number of instances:1
    -Exit from static constructor.
    Trying to get another Singleton instance, called secondInstance.
    The firstInstance and secondInstance are the same.
    Initializing database
    34900000
    4
    Tokyo has population 33200000
    Seoul has population 17500000
    

      

  • 相关阅读:
    Python3 -- 多线程(threading模块、queue模块)
    MySQL -- 常用汇总
    MySQL -- 常用函数汇总
    MySQL -- 数据表添加字段(三种方式)
    MySQL -- 查看表结构命令
    MySQL -- 修改/删除字段
    MySQL -- ALTER TABLE:修改数据表
    MySQL -- 单行注释和多行注释
    GCC 提供的原子操作
    内存区划分、内存分配、常量存储区、堆、栈、自由存储区、全局区[C++][内存管理][转载]
  • 原文地址:https://www.cnblogs.com/geovindu/p/16759642.html
Copyright © 2020-2023  润新知