Last active
August 29, 2015 14:00
-
-
Save felipegtx/94718ab161ebcbc643ab to your computer and use it in GitHub Desktop.
C# singleton class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// SimpleLocker class avaliable at: https://gist.github.com/felipegtx/6107975 | |
public sealed class SingletonFor<TheType> | |
{ | |
private static Func<TheType> _instanceBuilder = null; | |
private Func<TheType> _constructorCall = null; | |
private SimpleLocker _locker = null; | |
private bool _isInitialized = false; | |
private TheType _instance; | |
public bool IsInitialized { get { return _locker.Read(() => _isInitialized); } } | |
public bool UnprotectedIsInitialized { get { return _isInitialized; } } | |
public SingletonFor(Func<TheType> constructorCall) | |
: this(constructorCall, 1000) { } | |
public SingletonFor(Func<TheType> constructorCall, int contructorLockTimeout) | |
{ | |
if (_instanceBuilder == null) { _instanceBuilder = BuildInstance; } | |
if (constructorCall == null) { throw new ArgumentNullException("constructorCall"); } | |
_constructorCall = constructorCall; | |
_locker = new SimpleLocker(contructorLockTimeout); | |
} | |
/// <summary> | |
/// Changes the global builder for a given type | |
/// <remarks>This method should NEVER be used in a production code. It is intended only for creating detours for Unity Tests routines.</remarks> | |
/// </summary> | |
/// <param name="newGlobalBuilder">The builder body that is to be used globaly whenever an instance of this types is requested.</param> | |
[Obsolete("This method should NEVER be used in a production code. It is intended only for creating detours for Unity Tests routines.")] | |
public static void SetBuilderAs(Func<TheType> newGlobalBuilder) | |
{ | |
_instanceBuilder = newGlobalBuilder; | |
} | |
public TheType GetInstance() | |
{ | |
return _instanceBuilder(); | |
} | |
private TheType BuildInstance() | |
{ | |
if (!_locker.UpgradeableRead(() => this.UnprotectedIsInitialized)) | |
{ | |
_locker.WriteVoid(() => | |
{ | |
if (!this.UnprotectedIsInitialized) | |
{ | |
_instance = _constructorCall(); | |
_isInitialized = true; | |
} | |
}); | |
} | |
return this._instance; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment