Skip to content

Instantly share code, notes, and snippets.

@felipegtx
Last active August 29, 2015 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save felipegtx/94718ab161ebcbc643ab to your computer and use it in GitHub Desktop.
Save felipegtx/94718ab161ebcbc643ab to your computer and use it in GitHub Desktop.
C# singleton class
/// 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