/// <summary> /// Creates a new Singleton. /// </summary> /// <param name="getInstanceFunction">A function to create an instance of the given type. If null will be set to default constructor of this type.</param> /// <param name="initializeDirectly">Shall the Singleton be directly initialized upfront?</param> /// <exception cref="MissingMethodException">Throws a MissingMethodException when no getInstanceFunction is given and the type does not contain a default constructor and is no ValueType.</exception> public Singleton(Func <T> getInstanceFunction = null, bool initializeDirectly = false) { _instance = default(T); _getInstance = getInstanceFunction; if (_getInstance == null) { var ctor = typeof(T).GetConstructor(Type.EmptyTypes); if (ctor == null) { if (typeof(T).IsValueType) { _initialized = true; // has already been initialized in the first line to default(T). return; } else { throw new MissingMethodException("There is no empty constructor defined for this type. Please implement an empty constructor or provide a initialization function."); } } else // just for code clarity. { // Create method to call the empty constructor for the given type. // See https://stackoverflow.com/questions/10593630/create-delegate-from-constructor DynamicMethod dynamic = new DynamicMethod(string.Empty, typeof(T), Type.EmptyTypes, typeof(T)); ILGenerator il = dynamic.GetILGenerator(); il.DeclareLocal(typeof(T)); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ret); _getInstance = (Func <T>)dynamic.CreateDelegate(typeof(Func <T>)); } } if (initializeDirectly) { if (!_initialized) { _instance = _getInstance(); } _initialized = true; } else { _singletonLock = new UsableMutexSlim(); } }