Skip to content

Commit c975f66

Browse files
committed
Fixes #102
1 parent b362b06 commit c975f66

11 files changed

+100
-115
lines changed

src/Dependency/Injection/Members/InjectionFactory.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,7 @@ public override void AddPolicies<TContext, TPolicySet>(Type registeredType, Type
7979

8080
ResolveDelegate<TContext> CreateLegacyPolicy()
8181
{
82-
return (ref TContext c) =>
83-
_factoryFunc(c.Container, c.Type, c.Name) ??
84-
throw new InvalidOperationException("Injection Factory must return valid object or throw an exception");
82+
return (ref TContext c) => _factoryFunc(c.Container, c.Type, c.Name);
8583
}
8684

8785
ResolveDelegate<TContext> CreatePerResolveLegacyPolicy()

src/Lifetime/Abstracts/LifetimeManager.cs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ namespace Unity.Lifetime
88
/// </summary>
99
public abstract class LifetimeManager
1010
{
11+
/// <summary>
12+
/// This value represents Invalid Value. Lifetime manager must return this value
13+
/// unless value is set to valid object. Null is a valie value and is not equal
14+
/// to NoValue
15+
/// </summary>
16+
public static readonly object NoValue = new InvalidValue();
17+
1118
/// <summary>
1219
/// A <see cref="Boolean"/> indicating if this manager is being used in
1320
/// one of the registrations.
@@ -27,7 +34,7 @@ public abstract class LifetimeManager
2734
/// </summary>
2835
/// <param name="container">The container this lifetime is associated with</param>
2936
/// <returns>the object desired, or null if no such object is currently stored.</returns>
30-
public abstract object GetValue(ILifetimeContainer container = null);
37+
public virtual object GetValue(ILifetimeContainer container = null) => NoValue;
3138

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

56-
/// <summary>
57-
/// Type of current lifetime manager
58-
/// </summary>
59-
/// <returns>The <see cref="Type"/> of the manager.</returns>
60-
[Obsolete("This property will be removed in next major release. Use GetType() instead", false)]
61-
public Type LifetimeType => GetType();
62-
6363
#endregion
6464

6565

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

7474
#endregion
75+
76+
77+
#region Nested Types
78+
79+
public class InvalidValue
80+
{
81+
public override bool Equals(object obj)
82+
{
83+
return ReferenceEquals(this, obj);
84+
}
85+
86+
public override int GetHashCode()
87+
{
88+
return base.GetHashCode();
89+
}
90+
}
91+
92+
#endregion
7593
}
7694
}

src/Lifetime/Abstracts/SynchronizedLifetimeManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public override object GetValue(ILifetimeContainer container = null)
3333
{
3434
Monitor.Enter(_lockObj);
3535
var result = SynchronizedGetValue(container);
36-
if (result != null)
36+
if (NoValue != result)
3737
{
3838
Monitor.Exit(_lockObj);
3939
}

src/Lifetime/Managers/ContainerControlledLifetimeManager.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class ContainerControlledLifetimeManager : SynchronizedLifetimeManager,
3131
/// An instance of the object this manager is associated with.
3232
/// </summary>
3333
/// <value>This field holds a strong reference to the associated object.</value>
34-
protected object Value;
34+
protected object Value = NoValue;
3535

3636
private Func<ILifetimeContainer, object> _currentGetValue;
3737
private Action<object, ILifetimeContainer> _currentSetValue;
@@ -105,12 +105,12 @@ protected override void Dispose(bool disposing)
105105
{
106106
try
107107
{
108-
if (Value == null) return;
108+
if (NoValue == Value) return;
109109
if (Value is IDisposable disposable)
110110
{
111111
disposable.Dispose();
112112
}
113-
Value = null;
113+
Value = NoValue;
114114
}
115115
finally
116116
{

src/Lifetime/Managers/ContainerControlledTransientManager.cs

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,34 +19,19 @@ public override void SetValue(object newValue, ILifetimeContainer container = nu
1919
}
2020

2121
/// <inheritdoc/>
22-
public override object GetValue(ILifetimeContainer container = null)
23-
{
24-
return null;
25-
}
26-
27-
/// <inheritdoc/>
28-
public override void RemoveValue(ILifetimeContainer container = null)
29-
{
30-
}
22+
protected override LifetimeManager OnCreateLifetimeManager() => this;
3123

3224
/// <inheritdoc/>
33-
protected override LifetimeManager OnCreateLifetimeManager()
25+
public override bool InUse
3426
{
35-
return this;
27+
get => false;
28+
set { }
3629
}
3730

38-
/// <inheritdoc/>
39-
public override bool InUse { get => false; set => base.InUse = false; }
40-
41-
42-
#region Overrides
43-
4431
/// <summary>
4532
/// This method provides human readable representation of the lifetime
4633
/// </summary>
4734
/// <returns>Name of the lifetime</returns>
4835
public override string ToString() => "Lifetime:PerContainerTransient";
49-
50-
#endregion
5136
}
5237
}

src/Lifetime/Managers/ExternallyControlledLifetimeManager.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,14 @@ public class ExternallyControlledLifetimeManager : LifetimeManager,
1111
ITypeLifetimeManager,
1212
IFactoryLifetimeManager
1313
{
14-
private WeakReference _value = new WeakReference(null);
14+
#region Fields
15+
16+
private WeakReference _value = new WeakReference(NoValue);
17+
18+
#endregion
19+
20+
21+
#region Overrides
1522

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

41-
42-
#region Overrides
43-
4448
public override string ToString() => "Lifetime:External";
4549

4650
#endregion

src/Lifetime/Managers/HierarchicalLifetimeManager.cs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,14 @@ public class HierarchicalLifetimeManager : SynchronizedLifetimeManager,
3535

3636
#endregion
3737

38+
39+
#region Overrides
40+
3841
/// <inheritdoc/>
3942
protected override object SynchronizedGetValue(ILifetimeContainer container = null)
4043
{
4144
return _values.TryGetValue(container ?? throw new ArgumentNullException(nameof(container)),
42-
out object value) ? value : null;
45+
out object value) ? value : NoValue;
4346
}
4447

4548
/// <inheritdoc/>
@@ -69,6 +72,14 @@ protected override LifetimeManager OnCreateLifetimeManager()
6972
return new HierarchicalLifetimeManager();
7073
}
7174

75+
/// <summary>
76+
/// This method provides human readable representation of the lifetime
77+
/// </summary>
78+
/// <returns>Name of the lifetime</returns>
79+
public override string ToString() => "Lifetime:Hierarchical";
80+
81+
#endregion
82+
7283

7384
#region IDisposable
7485

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

8293
foreach (var disposable in _values.Values
83-
.OfType<IDisposable>()
84-
.ToArray())
94+
.OfType<IDisposable>()
95+
.ToArray())
8596
{
8697
disposable.Dispose();
8798
}
8899
_values.Clear();
89100
}
90-
finally
101+
finally
91102
{
92103
base.Dispose(disposing);
93104
}
@@ -96,17 +107,6 @@ protected override void Dispose(bool disposing)
96107
#endregion
97108

98109

99-
#region Overrides
100-
101-
/// <summary>
102-
/// This method provides human readable representation of the lifetime
103-
/// </summary>
104-
/// <returns>Name of the lifetime</returns>
105-
public override string ToString() => "Lifetime:Hierarchical";
106-
107-
#endregion
108-
109-
110110
#region Nested Types
111111

112112
private class DisposableAction : IDisposable

src/Lifetime/Managers/PerResolveLifetimeManager.cs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,14 @@ public class PerResolveLifetimeManager : LifetimeManager,
1010
IFactoryLifetimeManager,
1111
ITypeLifetimeManager
1212
{
13-
protected object value;
13+
#region Fields
1414

15-
/// <summary>
16-
/// Construct a new <see cref="PerResolveLifetimeManager"/> object that does not
17-
/// itself manage an instance.
18-
/// </summary>
19-
public PerResolveLifetimeManager()
20-
{
21-
value = null;
22-
}
15+
protected object value = NoValue;
16+
17+
#endregion
18+
19+
20+
#region Overrides
2321

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

36-
37-
#region Overrides
38-
3934
/// <summary>
4035
/// This method provides human readable representation of the lifetime
4136
/// </summary>

src/Lifetime/Managers/PerThreadLifetimeManager.cs

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,43 +24,33 @@ public class PerThreadLifetimeManager : LifetimeManager,
2424
IFactoryLifetimeManager,
2525
ITypeLifetimeManager
2626
{
27+
#region Fields
28+
2729
[ThreadStatic]
2830
private static Dictionary<Guid, object> _values;
29-
private readonly Guid _key;
31+
private readonly Guid _key = Guid.NewGuid();
3032

31-
/// <summary>
32-
/// Initializes a new instance of the <see cref="PerThreadLifetimeManager"/> class.
33-
/// </summary>
34-
public PerThreadLifetimeManager()
35-
{
36-
_key = Guid.NewGuid();
37-
}
33+
#endregion
34+
35+
36+
#region Overrides
3837

3938
/// <inheritdoc/>
4039
public override object GetValue(ILifetimeContainer container = null)
4140
{
42-
EnsureValues();
41+
if (null == _values) return NoValue;
4342

44-
_values.TryGetValue(_key, out var result);
45-
46-
return result;
43+
return _values.TryGetValue(_key, out var result) ? result : NoValue;
4744
}
4845

4946
/// <inheritdoc/>
5047
public override void SetValue(object newValue, ILifetimeContainer container = null)
51-
{
52-
EnsureValues();
53-
54-
_values[_key] = newValue;
55-
}
56-
57-
private static void EnsureValues()
5848
{
5949
// no need for locking, values is TLS
6050
if (_values == null)
61-
{
6251
_values = new Dictionary<Guid, object>();
63-
}
52+
53+
_values[_key] = newValue;
6454
}
6555

6656
/// <inheritdoc/>
@@ -70,7 +60,6 @@ protected override LifetimeManager OnCreateLifetimeManager()
7060
}
7161

7262

73-
#region Overrides
7463

7564
/// <summary>
7665
/// This method provides human readable representation of the lifetime

src/Lifetime/Managers/SingletonLifetimeManager.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,12 @@ public class SingletonLifetimeManager : SynchronizedLifetimeManager,
3333
/// An instance of the singleton object this manager is associated with.
3434
/// </summary>
3535
/// <value>This field holds a strong reference to the singleton object.</value>
36-
protected object Value;
36+
protected object Value = NoValue;
3737

3838
#endregion
39+
40+
41+
#region Overrides
3942

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

67+
/// <summary>
68+
/// This method provides human readable representation of the lifetime
69+
/// </summary>
70+
/// <returns>Name of the lifetime</returns>
71+
public override string ToString() => "Lifetime:Singleton";
72+
73+
#endregion
74+
75+
6476
#region IDisposable
6577

6678
/// <inheritdoc/>
6779
protected override void Dispose(bool disposing)
6880
{
6981
base.Dispose(disposing);
7082

71-
if (Value == null) return;
83+
if (NoValue == Value) return;
7284
if (Value is IDisposable disposable)
7385
{
7486
disposable.Dispose();
7587
}
76-
Value = null;
88+
Value = NoValue;
7789
}
7890

7991
#endregion
80-
81-
82-
#region Overrides
83-
84-
/// <summary>
85-
/// This method provides human readable representation of the lifetime
86-
/// </summary>
87-
/// <returns>Name of the lifetime</returns>
88-
public override string ToString() => "Lifetime:Singleton";
89-
90-
#endregion
9192
}
9293
}

0 commit comments

Comments
 (0)