public class WeakLazy<T> : IDisposable
{
private readonly WeakReference _weakReference;
private T _instance;
private Func<T> _valueFactory;
private readonly bool _isWeak;
private readonly bool _isThreadSafe;
private readonly object _lockObj;
public WeakLazy(bool isWeak)
: this(isWeak, false)
{ }
public WeakLazy(Func<T> valueFactory)
: this(valueFactory, false)
{ }
public WeakLazy(Func<T> valueFactory, bool isWeak)
: this(valueFactory, isWeak, false)
{ }
public WeakLazy(bool isWeak, bool isThreadSafe)
: this(default(Func<T>), isWeak, isThreadSafe)
{
}
public WeakLazy(Func<T> valueFactory, bool isWeak, bool isThreadSafe)
{
_valueFactory = valueFactory;
_isThreadSafe = isThreadSafe;
if (isThreadSafe)
_lockObj = new object();
_isWeak = isWeak;
if (isWeak)
_weakReference = new WeakReference(null);
}
public bool IsWeak
{ get { return _isWeak; } }
public bool IsThreadSafe
{ get { return _isThreadSafe; } }
public bool IsValueCreated
{
get
{
if (_isWeak)
return _weakReference.IsAlive;
else
return _instance != null;
}
}
public T Value
{
get
{
if (_isWeak)
return GetWeakInstance();
return GetInstance();
}
}
private T GetInstance()
{
if (_isThreadSafe)
{
if (_instance == null)
{
lock (_lockObj)
{
if (_instance == null)
_instance = CreateInstance();
}
}
return _instance;
}
else
{
if (_instance == null)
_instance = CreateInstance();
return _instance;
}
}
private T GetWeakInstance()
{
if (_isThreadSafe)
{
lock (_lockObj)
{
if (!_weakReference.IsAlive)
_weakReference.Target = CreateInstance();
return (T)_weakReference.Target;
}
}
else
{
if (!_weakReference.IsAlive)
_weakReference.Target = CreateInstance();
return (T)_weakReference.Target;
}
}
private T CreateInstance()
{
if (_valueFactory == default(Func<T>))
return Activator.CreateInstance<T>();
return _valueFactory();
}
public void Dispose()
{
if (!this._isWeak)
{
var disposeObj = this._instance as IDisposable;
if (disposeObj != null)
disposeObj.Dispose();
this._instance = default(T);
}
this._valueFactory = default(Func<T>);
}
}