/// <summary> /// Decrements the reference count for the singleton instance of the given type, /// and calls its <see cref="IDisposable.Dispose"/> method if the reference /// count gets to zero. /// </summary> /// <param name="type">The singleton instance's class type.</param> /// <returns> /// Returns true if the singleton instance's reference count drops to zero and /// its <see cref="IDisposable.Dispose"/> method is called, otherwise returns false. /// </returns> public static bool Dereference(Type type) { //Since the singleton paradigm allows for only one instance of a // particular type, we will use the type as a key to identify which // singleton instance to return. Type key = type; IDisposableSingleton instance; lock (SingletonManagementMutex) { //Add the reference counter key if it does not exist. if (!SingletonInstanceReferenceCount.ContainsKey(key)) { SingletonInstanceReferenceCount.Add(key, 1); } //Add the singleton instance key if it does not exist. if (!SingletonInstances.ContainsKey(key)) { SingletonInstances.Add(key, null); } //If the reference count is 0, dispose the singleton instance. if (0 == (--SingletonInstanceReferenceCount[key])) { if (null != (instance = SingletonInstances[key])) { //Remove the reference from the singleton instance dictionary before disposing. SingletonInstances[key] = null; instance.DisposeWhenDereferenced(); return(true); } } return(false); } }
/// <summary> /// Gets the singleton instance of the specified class type that is managed /// by <see cref="DisposableSingletonManager"/>. If no instance exists, then /// one is created using the provided function or the type's parameterless contructor. /// This method also increments the singleton instance's reference count so that /// the instance's <see cref="IDisposable.Dispose"/> method is not called when there /// are multiple references to the instance in existence. /// </summary> /// <param name="createInstance"> /// A function to create the singleton instance, or null to use its parameterless contructor. /// </param> /// <param name="type">The singleton instance's class type.</param> /// <returns>Returns the singleton instance of the specified type.</returns> public static IDisposableSingleton GetInstance(Func <IDisposableSingleton> createInstance, Type type) { //Since the singleton paradigm allows for only one instance of a // particular type, we will use the type as a key to identify which // singleton instance to return. Type key = type; lock (SingletonManagementMutex) { //Add the reference counter key if it does not exist. if (!SingletonInstanceReferenceCount.ContainsKey(key)) { SingletonInstanceReferenceCount.Add(key, 0); } //Add the singleton instance key if it does not exist. if (!SingletonInstances.ContainsKey(key)) { SingletonInstances.Add(key, null); } //If the reference count is 0, create a new singleton instance. if (SingletonInstanceReferenceCount[key] == 0) { SingletonInstances[key] = CreateInstance(createInstance, type); } //Increment the reference count. SingletonInstanceReferenceCount[key]++; //Return the singleton instance. return(SingletonInstances[key] as IDisposableSingleton); } }