Skip to content

Commit

Permalink
Fixes #102
Browse files Browse the repository at this point in the history
  • Loading branch information
ENikS committed Apr 2, 2019
1 parent b362b06 commit c975f66
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 115 deletions.
4 changes: 1 addition & 3 deletions src/Dependency/Injection/Members/InjectionFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,7 @@ public override void AddPolicies<TContext, TPolicySet>(Type registeredType, Type

ResolveDelegate<TContext> CreateLegacyPolicy()
{
return (ref TContext c) =>
_factoryFunc(c.Container, c.Type, c.Name) ??
throw new InvalidOperationException("Injection Factory must return valid object or throw an exception");
return (ref TContext c) => _factoryFunc(c.Container, c.Type, c.Name);
}

ResolveDelegate<TContext> CreatePerResolveLegacyPolicy()
Expand Down
34 changes: 26 additions & 8 deletions src/Lifetime/Abstracts/LifetimeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ namespace Unity.Lifetime
/// </summary>
public abstract class LifetimeManager
{
/// <summary>
/// This value represents Invalid Value. Lifetime manager must return this value
/// unless value is set to valid object. Null is a valie value and is not equal
/// to NoValue
/// </summary>
public static readonly object NoValue = new InvalidValue();

/// <summary>
/// A <see cref="Boolean"/> indicating if this manager is being used in
/// one of the registrations.
Expand All @@ -27,7 +34,7 @@ public abstract class LifetimeManager
/// </summary>
/// <param name="container">The container this lifetime is associated with</param>
/// <returns>the object desired, or null if no such object is currently stored.</returns>
public abstract object GetValue(ILifetimeContainer container = null);
public virtual object GetValue(ILifetimeContainer container = null) => NoValue;

/// <summary>
/// Stores the given value into backing store for retrieval later.
Expand All @@ -53,13 +60,6 @@ public virtual void RemoveValue(ILifetimeContainer container = null) { }
/// <returns>A new instance of the appropriate lifetime manager</returns>
public LifetimeManager CreateLifetimePolicy() => OnCreateLifetimeManager();

/// <summary>
/// Type of current lifetime manager
/// </summary>
/// <returns>The <see cref="Type"/> of the manager.</returns>
[Obsolete("This property will be removed in next major release. Use GetType() instead", false)]
public Type LifetimeType => GetType();

#endregion


Expand All @@ -72,5 +72,23 @@ public virtual void RemoveValue(ILifetimeContainer container = null) { }
protected abstract LifetimeManager OnCreateLifetimeManager();

#endregion


#region Nested Types

public class InvalidValue
{
public override bool Equals(object obj)
{
return ReferenceEquals(this, obj);
}

public override int GetHashCode()
{
return base.GetHashCode();
}
}

#endregion
}
}
2 changes: 1 addition & 1 deletion src/Lifetime/Abstracts/SynchronizedLifetimeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public override object GetValue(ILifetimeContainer container = null)
{
Monitor.Enter(_lockObj);
var result = SynchronizedGetValue(container);
if (result != null)
if (NoValue != result)
{
Monitor.Exit(_lockObj);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Lifetime/Managers/ContainerControlledLifetimeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class ContainerControlledLifetimeManager : SynchronizedLifetimeManager,
/// An instance of the object this manager is associated with.
/// </summary>
/// <value>This field holds a strong reference to the associated object.</value>
protected object Value;
protected object Value = NoValue;

private Func<ILifetimeContainer, object> _currentGetValue;
private Action<object, ILifetimeContainer> _currentSetValue;
Expand Down Expand Up @@ -105,12 +105,12 @@ protected override void Dispose(bool disposing)
{
try
{
if (Value == null) return;
if (NoValue == Value) return;
if (Value is IDisposable disposable)
{
disposable.Dispose();
}
Value = null;
Value = NoValue;
}
finally
{
Expand Down
23 changes: 4 additions & 19 deletions src/Lifetime/Managers/ContainerControlledTransientManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,19 @@ public override void SetValue(object newValue, ILifetimeContainer container = nu
}

/// <inheritdoc/>
public override object GetValue(ILifetimeContainer container = null)
{
return null;
}

/// <inheritdoc/>
public override void RemoveValue(ILifetimeContainer container = null)
{
}
protected override LifetimeManager OnCreateLifetimeManager() => this;

/// <inheritdoc/>
protected override LifetimeManager OnCreateLifetimeManager()
public override bool InUse
{
return this;
get => false;
set { }
}

/// <inheritdoc/>
public override bool InUse { get => false; set => base.InUse = false; }


#region Overrides

/// <summary>
/// This method provides human readable representation of the lifetime
/// </summary>
/// <returns>Name of the lifetime</returns>
public override string ToString() => "Lifetime:PerContainerTransient";

#endregion
}
}
12 changes: 8 additions & 4 deletions src/Lifetime/Managers/ExternallyControlledLifetimeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ public class ExternallyControlledLifetimeManager : LifetimeManager,
ITypeLifetimeManager,
IFactoryLifetimeManager
{
private WeakReference _value = new WeakReference(null);
#region Fields

private WeakReference _value = new WeakReference(NoValue);

#endregion


#region Overrides

/// <summary>
/// Retrieve a value from the backing store associated with this Lifetime policy.
Expand All @@ -38,9 +45,6 @@ protected override LifetimeManager OnCreateLifetimeManager()
return new ExternallyControlledLifetimeManager();
}


#region Overrides

public override string ToString() => "Lifetime:External";

#endregion
Expand Down
30 changes: 15 additions & 15 deletions src/Lifetime/Managers/HierarchicalLifetimeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ public class HierarchicalLifetimeManager : SynchronizedLifetimeManager,

#endregion


#region Overrides

/// <inheritdoc/>
protected override object SynchronizedGetValue(ILifetimeContainer container = null)
{
return _values.TryGetValue(container ?? throw new ArgumentNullException(nameof(container)),
out object value) ? value : null;
out object value) ? value : NoValue;
}

/// <inheritdoc/>
Expand Down Expand Up @@ -69,6 +72,14 @@ protected override LifetimeManager OnCreateLifetimeManager()
return new HierarchicalLifetimeManager();
}

/// <summary>
/// This method provides human readable representation of the lifetime
/// </summary>
/// <returns>Name of the lifetime</returns>
public override string ToString() => "Lifetime:Hierarchical";

#endregion


#region IDisposable

Expand All @@ -80,14 +91,14 @@ protected override void Dispose(bool disposing)
if (0 == _values.Count) return;

foreach (var disposable in _values.Values
.OfType<IDisposable>()
.ToArray())
.OfType<IDisposable>()
.ToArray())
{
disposable.Dispose();
}
_values.Clear();
}
finally
finally
{
base.Dispose(disposing);
}
Expand All @@ -96,17 +107,6 @@ protected override void Dispose(bool disposing)
#endregion


#region Overrides

/// <summary>
/// This method provides human readable representation of the lifetime
/// </summary>
/// <returns>Name of the lifetime</returns>
public override string ToString() => "Lifetime:Hierarchical";

#endregion


#region Nested Types

private class DisposableAction : IDisposable
Expand Down
19 changes: 7 additions & 12 deletions src/Lifetime/Managers/PerResolveLifetimeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@ public class PerResolveLifetimeManager : LifetimeManager,
IFactoryLifetimeManager,
ITypeLifetimeManager
{
protected object value;
#region Fields

/// <summary>
/// Construct a new <see cref="PerResolveLifetimeManager"/> object that does not
/// itself manage an instance.
/// </summary>
public PerResolveLifetimeManager()
{
value = null;
}
protected object value = NoValue;

#endregion


#region Overrides

/// <inheritdoc/>
public override object GetValue(ILifetimeContainer container = null)
Expand All @@ -33,9 +31,6 @@ protected override LifetimeManager OnCreateLifetimeManager()
return new PerResolveLifetimeManager();
}


#region Overrides

/// <summary>
/// This method provides human readable representation of the lifetime
/// </summary>
Expand Down
33 changes: 11 additions & 22 deletions src/Lifetime/Managers/PerThreadLifetimeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,43 +24,33 @@ public class PerThreadLifetimeManager : LifetimeManager,
IFactoryLifetimeManager,
ITypeLifetimeManager
{
#region Fields

[ThreadStatic]
private static Dictionary<Guid, object> _values;
private readonly Guid _key;
private readonly Guid _key = Guid.NewGuid();

/// <summary>
/// Initializes a new instance of the <see cref="PerThreadLifetimeManager"/> class.
/// </summary>
public PerThreadLifetimeManager()
{
_key = Guid.NewGuid();
}
#endregion


#region Overrides

/// <inheritdoc/>
public override object GetValue(ILifetimeContainer container = null)
{
EnsureValues();
if (null == _values) return NoValue;

_values.TryGetValue(_key, out var result);

return result;
return _values.TryGetValue(_key, out var result) ? result : NoValue;
}

/// <inheritdoc/>
public override void SetValue(object newValue, ILifetimeContainer container = null)
{
EnsureValues();

_values[_key] = newValue;
}

private static void EnsureValues()
{
// no need for locking, values is TLS
if (_values == null)
{
_values = new Dictionary<Guid, object>();
}

_values[_key] = newValue;
}

/// <inheritdoc/>
Expand All @@ -70,7 +60,6 @@ protected override LifetimeManager OnCreateLifetimeManager()
}


#region Overrides

/// <summary>
/// This method provides human readable representation of the lifetime
Expand Down
29 changes: 15 additions & 14 deletions src/Lifetime/Managers/SingletonLifetimeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ public class SingletonLifetimeManager : SynchronizedLifetimeManager,
/// An instance of the singleton object this manager is associated with.
/// </summary>
/// <value>This field holds a strong reference to the singleton object.</value>
protected object Value;
protected object Value = NoValue;

#endregion


#region Overrides

/// <inheritdoc/>
protected override object SynchronizedGetValue(ILifetimeContainer container = null)
Expand All @@ -61,32 +64,30 @@ protected override LifetimeManager OnCreateLifetimeManager()
return new SingletonLifetimeManager();
}

/// <summary>
/// This method provides human readable representation of the lifetime
/// </summary>
/// <returns>Name of the lifetime</returns>
public override string ToString() => "Lifetime:Singleton";

#endregion


#region IDisposable

/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);

if (Value == null) return;
if (NoValue == Value) return;
if (Value is IDisposable disposable)
{
disposable.Dispose();
}
Value = null;
Value = NoValue;
}

#endregion


#region Overrides

/// <summary>
/// This method provides human readable representation of the lifetime
/// </summary>
/// <returns>Name of the lifetime</returns>
public override string ToString() => "Lifetime:Singleton";

#endregion
}
}
Loading

0 comments on commit c975f66

Please sign in to comment.