Skip to content

Commit 7ef35be

Browse files
committed
Merge branch 'v5.x' of https://github.com/unitycontainer/container into v5.x
2 parents 776d81a + 1ce7a54 commit 7ef35be

35 files changed

+1228
-932
lines changed

src/Extensions/DefaultLifetime.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using Unity.Extension;
3+
using Unity.Lifetime;
4+
5+
namespace Unity
6+
{
7+
public class DefaultLifetime : UnityContainerExtension
8+
{
9+
protected override void Initialize()
10+
{
11+
}
12+
13+
#region Public Members
14+
15+
public ITypeLifetimeManager TypeDefaultLifetime
16+
{
17+
get => (ITypeLifetimeManager)((UnityContainer)Container).TypeLifetimeManager;
18+
set => ((UnityContainer)Container).TypeLifetimeManager = (LifetimeManager)value ??
19+
throw new ArgumentNullException("Type Lifetime Manager can not be null");
20+
}
21+
22+
public IInstanceLifetimeManager InstanceDefaultLifetime
23+
{
24+
get => (IInstanceLifetimeManager)((UnityContainer)Container).InstanceLifetimeManager;
25+
set => ((UnityContainer)Container).InstanceLifetimeManager = (LifetimeManager)value ??
26+
throw new ArgumentNullException("Instance Lifetime Manager can not be null");
27+
}
28+
29+
public IFactoryLifetimeManager FactoryDefaultLifetime
30+
{
31+
get => (IFactoryLifetimeManager)((UnityContainer)Container).FactoryLifetimeManager;
32+
set => ((UnityContainer)Container).FactoryLifetimeManager = (LifetimeManager)value ??
33+
throw new ArgumentNullException("Factory Lifetime Manager can not be null");
34+
}
35+
36+
#endregion
37+
}
38+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System;
2+
using System.Linq;
3+
using System.Reflection;
4+
using Unity.Builder;
5+
using Unity.Policy;
6+
using Unity.Resolution;
7+
8+
namespace Unity.Factories
9+
{
10+
public class EnumerableResolver
11+
{
12+
#region Fields
13+
14+
private static readonly MethodInfo EnumerableMethod =
15+
typeof(EnumerableResolver).GetTypeInfo()
16+
.GetDeclaredMethod(nameof(EnumerableResolver.Resolver));
17+
18+
private static readonly MethodInfo EnumerableFactory =
19+
typeof(EnumerableResolver).GetTypeInfo()
20+
.GetDeclaredMethod(nameof(EnumerableResolver.ResolverFactory));
21+
22+
#endregion
23+
24+
25+
#region ResolveDelegateFactory
26+
27+
public static ResolveDelegateFactory Factory = (ref BuilderContext context) =>
28+
{
29+
30+
#if NETSTANDARD1_0 || NETCOREAPP1_0 || NET40
31+
var typeArgument = context.Type.GetTypeInfo().GenericTypeArguments.First();
32+
if (typeArgument.GetTypeInfo().IsGenericType)
33+
#else
34+
var typeArgument = context.Type.GenericTypeArguments.First();
35+
if (typeArgument.IsGenericType)
36+
#endif
37+
{
38+
return ((EnumerableFactoryDelegate)
39+
EnumerableFactory.MakeGenericMethod(typeArgument)
40+
.CreateDelegate(typeof(EnumerableFactoryDelegate)))();
41+
}
42+
else
43+
{
44+
return (ResolveDelegate<BuilderContext>)
45+
EnumerableMethod.MakeGenericMethod(typeArgument)
46+
.CreateDelegate(typeof(ResolveDelegate<BuilderContext>));
47+
}
48+
};
49+
50+
#endregion
51+
52+
53+
#region Implementation
54+
55+
private static object Resolver<TElement>(ref BuilderContext context)
56+
{
57+
return ((UnityContainer)context.Container).ResolveEnumerable<TElement>(context.Resolve,
58+
context.Name);
59+
}
60+
61+
private static ResolveDelegate<BuilderContext> ResolverFactory<TElement>()
62+
{
63+
Type type = typeof(TElement).GetGenericTypeDefinition();
64+
return (ref BuilderContext c) => ((UnityContainer)c.Container).ResolveEnumerable<TElement>(c.Resolve, type, c.Name);
65+
}
66+
67+
#endregion
68+
69+
70+
#region Nested Types
71+
72+
private delegate ResolveDelegate<BuilderContext> EnumerableFactoryDelegate();
73+
74+
#endregion
75+
}
76+
}

src/Lifetime/ContainerLifetimeManager.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,7 @@ protected override LifetimeManager OnCreateLifetimeManager()
1919
{
2020
return new ContainerLifetimeManager();
2121
}
22+
23+
public override bool InUse { get => false; set => base.InUse = false; }
2224
}
2325
}

src/Processors/Abstracts/MemberExpression.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,13 @@ protected virtual IEnumerable<Expression> ExpressionsFromSelection(Type type, IE
3131

3232
yield return GetResolverExpression(info, value);
3333
break;
34-
3534

3635
// Injection Member
3736
case InjectionMember<TMemberInfo, TData> injectionMember:
3837
yield return GetResolverExpression(injectionMember.MemberInfo(type),
3938
injectionMember.Data);
4039
break;
4140

42-
4341
// Unknown
4442
default:
4543
throw new InvalidOperationException($"Unknown MemberInfo<{typeof(TMemberInfo)}> type");

src/Processors/Constructor/ConstructorExpression.cs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq.Expressions;
55
using System.Reflection;
66
using Unity.Builder;
7+
using Unity.Exceptions;
78
using Unity.Injection;
89
using Unity.Lifetime;
910
using Unity.Policy;
@@ -96,13 +97,21 @@ protected override Expression GetResolverExpression(ConstructorInfo info, object
9697
var variable = Expression.Variable(info.DeclaringType);
9798
var parametersExpr = CreateParameterExpressions(info.GetParameters(), resolvers);
9899

99-
return Expression.IfThen(
100-
Expression.Equal(Expression.Constant(null), BuilderContextExpression.Existing),
101-
Expression.Block(new[] { variable }, new Expression[]
102-
{
103-
Expression.Assign(variable, Expression.New(info, parametersExpr)),
104-
Expression.Assign(BuilderContextExpression.Existing, Expression.Convert(variable, typeof(object)))
105-
}));
100+
try
101+
{
102+
return Expression.IfThen(
103+
Expression.Equal(Expression.Constant(null), BuilderContextExpression.Existing),
104+
Expression.Block(new[] { variable }, new Expression[]
105+
{
106+
Expression.Assign(variable, Expression.New(info, parametersExpr)),
107+
Expression.Assign(BuilderContextExpression.Existing, Expression.Convert(variable, typeof(object)))
108+
}));
109+
}
110+
catch (ArgumentException ex)
111+
{
112+
throw new InvalidRegistrationException("Invalid Argument", ex);
113+
}
114+
106115
}
107116

108117
#endregion

src/Processors/Methods/MethodProcessor.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq.Expressions;
55
using System.Reflection;
66
using Unity.Builder;
7+
using Unity.Exceptions;
78
using Unity.Policy;
89
using Unity.Resolution;
910

@@ -37,9 +38,16 @@ protected override IEnumerable<MethodInfo> DeclaredMembers(Type type)
3738

3839
protected override Expression GetResolverExpression(MethodInfo info, object resolvers)
3940
{
40-
return Expression.Call(
41-
Expression.Convert(BuilderContextExpression.Existing, info.DeclaringType),
42-
info, CreateParameterExpressions(info.GetParameters(), resolvers));
41+
try
42+
{
43+
return Expression.Call(
44+
Expression.Convert(BuilderContextExpression.Existing, info.DeclaringType),
45+
info, CreateParameterExpressions(info.GetParameters(), resolvers));
46+
}
47+
catch (ArgumentException ex)
48+
{
49+
throw new InvalidRegistrationException("Invalid Argument", ex);
50+
}
4351
}
4452

4553
#endregion

src/Storage/QuickSet.cs

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
using System;
2+
using System.Security;
3+
4+
namespace Unity.Storage
5+
{
6+
[SecuritySafeCritical]
7+
public class QuickSet<TValue>
8+
{
9+
#region Fields
10+
11+
private int _prime;
12+
private int[] Buckets;
13+
private Entry[] Entries;
14+
public int Count { get; private set; }
15+
16+
#endregion
17+
18+
19+
#region Constructors
20+
21+
public QuickSet()
22+
{
23+
var size = Primes[_prime];
24+
Buckets = new int[size];
25+
Entries = new Entry[size];
26+
27+
#if !NET40
28+
unsafe
29+
{
30+
fixed (int* bucketsPtr = Buckets)
31+
{
32+
int* ptr = bucketsPtr;
33+
var end = bucketsPtr + Buckets.Length;
34+
while (ptr < end) *ptr++ = -1;
35+
}
36+
}
37+
#else
38+
for(int i = 0; i < Buckets.Length; i++)
39+
Buckets[i] = -1;
40+
#endif
41+
}
42+
43+
#endregion
44+
45+
46+
#region Public Methods
47+
48+
public bool Add(int hashCode, TValue value)
49+
{
50+
var collisions = 0;
51+
var targetBucket = (hashCode & UnityContainer.HashMask) % Buckets.Length;
52+
53+
// Check for the existing
54+
for (var i = Buckets[targetBucket]; i >= 0; i = Entries[i].Next)
55+
{
56+
ref var candidate = ref Entries[i];
57+
if (candidate.HashCode != hashCode || !Equals(candidate.Value, value))
58+
{
59+
collisions++;
60+
continue;
61+
}
62+
63+
// Already exists
64+
return false;
65+
}
66+
67+
// Expand if required
68+
if (Count >= Entries.Length || 3 < collisions)
69+
{
70+
Expand();
71+
targetBucket = (hashCode & UnityContainer.HashMask) % Buckets.Length;
72+
}
73+
74+
// Add registration
75+
ref var entry = ref Entries[Count];
76+
entry.HashCode = hashCode;
77+
entry.Value = value;
78+
entry.Next = Buckets[targetBucket];
79+
Buckets[targetBucket] = Count++;
80+
81+
return true;
82+
}
83+
84+
#endregion
85+
86+
87+
#region Entry Type
88+
89+
private struct Entry
90+
{
91+
public int HashCode;
92+
public TValue Value;
93+
public int Next;
94+
}
95+
96+
#endregion
97+
98+
99+
#region Implementation
100+
101+
private void Expand()
102+
{
103+
var entries = Entries;
104+
105+
_prime += 1;
106+
107+
var size = Primes[_prime];
108+
Buckets = new int[size];
109+
Entries = new Entry[size];
110+
111+
#if !NET40
112+
unsafe
113+
{
114+
fixed (int* bucketsPtr = Buckets)
115+
{
116+
int* ptr = bucketsPtr;
117+
var end = bucketsPtr + Buckets.Length;
118+
while (ptr < end) *ptr++ = -1;
119+
}
120+
}
121+
#else
122+
for(int i = 0; i < Buckets.Length; i++)
123+
Buckets[i] = -1;
124+
#endif
125+
Array.Copy(entries, 0, Entries, 0, Count);
126+
for (var i = 0; i < Count; i++)
127+
{
128+
var hashCode = Entries[i].HashCode & UnityContainer.HashMask;
129+
if (hashCode < 0) continue;
130+
131+
var bucket = hashCode % Buckets.Length;
132+
Entries[i].Next = Buckets[bucket];
133+
Buckets[bucket] = i;
134+
}
135+
}
136+
137+
public static readonly int[] Primes = {
138+
11, 37, 71, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919, 1103, 1327, 1597,
139+
1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591, 17519, 21023,
140+
25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437, 187751,
141+
225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263,
142+
1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369};
143+
144+
#endregion
145+
}
146+
}

src/Storage/RegistrationSet.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,13 @@ public ref Entry this[int index]
4848

4949
public void Add(Type type, string name, InternalRegistration registration)
5050
{
51-
var hashCode = ((type?.GetHashCode() ?? 0 + 37) ^ (name?.GetHashCode() ?? 0 + 17)) & 0x7FFFFFFF;
51+
var hashCode = (37 ^ (name?.GetHashCode() ?? 0 + 17)) & 0x7FFFFFFF;
5252
var bucket = hashCode % _buckets.Length;
5353
var collisionCount = 0;
5454
for (int i = _buckets[bucket]; --i >= 0; i = _entries[i].Next)
5555
{
5656
ref var entry = ref _entries[i];
57-
if (entry.HashCode == hashCode && entry.RegisteredType == type)
57+
if (entry.HashCode == hashCode && entry.Name == name)
5858
{
5959
entry.RegisteredType = type;
6060
entry.Name = name;

0 commit comments

Comments
 (0)