namespace Quadarax.Foundation.Core.Object
{
  
        /// <summary>
        /// Well-known singleton pattern implementation.
        /// </summary>
        /// <remarks>
        /// The singleton type must inherit this class. The actual instance type is determined
        /// by the only type parameter. The singleton type must implement a default constructor.
        /// </remarks>
        /// <typeparam name="TInstance"></typeparam>
        public class Singleton<TInstance> where TInstance : new()
        {
            private static TInstance? _instance;
            private static readonly object _syncRoot = new object();

            /// <summary>
            /// Singleton instance
            /// </summary>
            public static TInstance Instance
            {
                get
                {
                    if (_instance == null)
                    {
                        lock (_syncRoot)
                        {
                            if (_instance == null)
                                _instance = new TInstance();
                        }
                    }

                    return _instance;
                }
            }
        }

        /// <summary>
        /// Well-known singleton pattern implementation.
        /// </summary>
        /// <remarks>
        /// The singleton type must inherit this class. The actual instance type is determined
        /// by the only type parameter. The singleton type must implement a default constructor.
        /// </remarks>
        /// <typeparam name="TInstance"></typeparam>
        /// <typeparam name="TInterface"></typeparam>
        public class Singleton<TInterface, TInstance>
            where TInstance : TInterface, new()
            where TInterface : class
        {
            private static volatile TInterface? _instance;
            private static readonly object _syncRoot = new object();

            public static TInterface Instance
            {
                get
                {
                    if (_instance == null)
                    {
                        lock (_syncRoot)
                        {
                            if (_instance == null)
                                _instance = new TInstance();
                        }
                    }

                    return _instance;
                }
            }
        }
}
