Skip to content

Commit 123d4bc

Browse files
committed
Merge branch 'master' of https://github.com/unitycontainer/container into v5.x
2 parents 85d5a8e + 7d3c404 commit 123d4bc

File tree

10 files changed

+107
-117
lines changed

10 files changed

+107
-117
lines changed

src/Processors/Abstracts/MemberExpression.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ protected virtual IEnumerable<Expression> ExpressionsFromSelection(Type type, IE
2525
var attribute = GetCustomAttribute(info, node.Type);
2626
if (null == attribute) continue;
2727

28-
value = null == node.Factory ? (object)attribute : node.Factory(attribute, info);
28+
value = null == node.Factory ? (object)attribute : node.Factory(attribute, info, null);
2929
break;
3030
}
3131

src/Processors/Abstracts/MemberProcessor.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@ public abstract class MemberProcessor
7777
#endregion
7878
}
7979

80-
public delegate ResolveDelegate<BuilderContext> AttributeResolverFactory(Attribute attribute, object info, object value = null);
81-
8280
public abstract partial class MemberProcessor<TMemberInfo, TData> : MemberProcessor,
8381
ISelect<TMemberInfo>
8482
where TMemberInfo : MemberInfo
@@ -98,8 +96,8 @@ protected MemberProcessor(IPolicySet policySet)
9896
// Add Unity attribute factories
9997
AttributeFactories = new[]
10098
{
101-
new AttributeFactoryNode(typeof(DependencyAttribute), DependencyResolverFactory),
102-
new AttributeFactoryNode(typeof(OptionalDependencyAttribute), OptionalDependencyResolverFactory),
99+
new AttributeFactoryNode(typeof(DependencyAttribute), (a)=>((DependencyResolutionAttribute)a).Name, DependencyResolverFactory),
100+
new AttributeFactoryNode(typeof(OptionalDependencyAttribute), (a)=>((DependencyResolutionAttribute)a).Name, OptionalDependencyResolverFactory),
103101
};
104102

105103
_policySet = policySet;
@@ -110,9 +108,9 @@ protected MemberProcessor(IPolicySet policySet, Type attribute)
110108
// Add Unity attribute factories
111109
AttributeFactories = new[]
112110
{
113-
new AttributeFactoryNode(attribute, null),
114-
new AttributeFactoryNode(typeof(DependencyAttribute), DependencyResolverFactory),
115-
new AttributeFactoryNode(typeof(OptionalDependencyAttribute), OptionalDependencyResolverFactory),
111+
new AttributeFactoryNode(attribute, (a)=>(a as DependencyResolutionAttribute)?.Name, null),
112+
new AttributeFactoryNode(typeof(DependencyAttribute), (a)=>((DependencyResolutionAttribute)a).Name, DependencyResolverFactory),
113+
new AttributeFactoryNode(typeof(OptionalDependencyAttribute), (a)=>((DependencyResolutionAttribute)a).Name, OptionalDependencyResolverFactory),
116114
};
117115
_policySet = policySet;
118116
}
@@ -122,7 +120,7 @@ protected MemberProcessor(IPolicySet policySet, Type attribute)
122120

123121
#region Public Methods
124122

125-
public void Add(Type type, AttributeResolverFactory resolutionFactory)
123+
public void Add(Type type, Func<Attribute, string> getName, Func<Attribute, object, object, ResolveDelegate<BuilderContext>> resolutionFactory)
126124
{
127125
for (var i = 0; i < AttributeFactories.Length; i++)
128126
{
@@ -134,7 +132,7 @@ public void Add(Type type, AttributeResolverFactory resolutionFactory)
134132

135133
var factories = new AttributeFactoryNode[AttributeFactories.Length + 1];
136134
Array.Copy(AttributeFactories, factories, AttributeFactories.Length);
137-
factories[AttributeFactories.Length] = new AttributeFactoryNode(type, resolutionFactory);
135+
factories[AttributeFactories.Length] = new AttributeFactoryNode(type, getName, resolutionFactory);
138136
AttributeFactories = factories;
139137
}
140138

@@ -296,11 +294,13 @@ protected virtual ResolveDelegate<BuilderContext> OptionalDependencyResolverFact
296294
public struct AttributeFactoryNode
297295
{
298296
public readonly Type Type;
299-
public AttributeResolverFactory Factory;
297+
public Func<Attribute, object, object, ResolveDelegate<BuilderContext>> Factory;
298+
public Func<Attribute, string> Name;
300299

301-
public AttributeFactoryNode(Type type, AttributeResolverFactory factory)
300+
public AttributeFactoryNode(Type type, Func<Attribute, string> getName, Func<Attribute, object, object, ResolveDelegate<BuilderContext>> factory)
302301
{
303302
Type = type;
303+
Name = getName;
304304
Factory = factory;
305305
}
306306
}

src/Processors/Abstracts/MemberResolution.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ protected virtual IEnumerable<ResolveDelegate<BuilderContext>> ResolversFromSele
2626
var attribute = GetCustomAttribute(info, node.Type);
2727
if (null == attribute) continue;
2828

29-
value = null == node.Factory ? (object)attribute : node.Factory(attribute, info);
29+
value = null == node.Factory ? (object)attribute : node.Factory(attribute, info, null);
3030
break;
3131
}
3232
yield return GetResolverDelegate(info, value);

src/Processors/Constructor/ConstructorDiagnostic.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ public class ConstructorDiagnostic : ConstructorProcessor
6868

6969
#region Constructors
7070

71-
public ConstructorDiagnostic(IPolicySet policySet, Func<Type, bool> isTypeRegistered)
72-
: base(policySet, isTypeRegistered)
71+
public ConstructorDiagnostic(IPolicySet policySet, UnityContainer container)
72+
: base(policySet, container)
7373
{
7474
}
7575

@@ -177,9 +177,9 @@ protected override object SmartSelector(Type type, ConstructorInfo[] constructor
177177
parametersCount = parameters.Length;
178178

179179
#if NET40
180-
if (parameters.All(p => (null != p.DefaultValue && !(p.DefaultValue is DBNull)) || CanResolve(p.ParameterType)))
180+
if (parameters.All(p => (null != p.DefaultValue && !(p.DefaultValue is DBNull)) || CanResolve(p)))
181181
#else
182-
if (parameters.All(p => p.HasDefaultValue || CanResolve(p.ParameterType)))
182+
if (parameters.All(p => p.HasDefaultValue || CanResolve(p)))
183183
#endif
184184
{
185185
if (bestCtor == null)

src/Processors/Constructor/ConstructorProcessor.cs

Lines changed: 4 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,11 @@ namespace Unity.Processors
1212
{
1313
public partial class ConstructorProcessor : ParametersProcessor<ConstructorInfo>
1414
{
15-
#region Fields
16-
17-
private readonly Func<Type, bool> _isTypeRegistered;
18-
private static readonly TypeInfo DelegateType = typeof(Delegate).GetTypeInfo();
19-
20-
#endregion
21-
22-
2315
#region Constructors
2416

25-
public ConstructorProcessor(IPolicySet policySet, Func<Type, bool> isTypeRegistered)
26-
: base(policySet, typeof(InjectionConstructorAttribute))
17+
public ConstructorProcessor(IPolicySet policySet, UnityContainer container)
18+
: base(policySet, typeof(InjectionConstructorAttribute), container)
2719
{
28-
_isTypeRegistered = isTypeRegistered;
2920
SelectMethod = SmartSelector;
3021
}
3122

@@ -148,9 +139,9 @@ protected virtual object SmartSelector(Type type, ConstructorInfo[] constructors
148139
{
149140
var parameters = ctorInfo.GetParameters();
150141
#if NET40
151-
if (parameters.All(p => (null != p.DefaultValue && !(p.DefaultValue is DBNull)) || CanResolve(p.ParameterType)))
142+
if (parameters.All(p => (null != p.DefaultValue && !(p.DefaultValue is DBNull)) || CanResolve(p)))
152143
#else
153-
if (parameters.All(p => p.HasDefaultValue || CanResolve(p.ParameterType)))
144+
if (parameters.All(p => p.HasDefaultValue || CanResolve(p)))
154145
#endif
155146
{
156147
return ctorInfo;
@@ -161,55 +152,6 @@ protected virtual object SmartSelector(Type type, ConstructorInfo[] constructors
161152
$"Failed to select a constructor for {type.FullName}", new InvalidRegistrationException());
162153
}
163154

164-
protected bool CanResolve(Type type)
165-
{
166-
#if NETSTANDARD1_0 || NETCOREAPP1_0
167-
var info = type.GetTypeInfo();
168-
#else
169-
var info = type;
170-
#endif
171-
if (info.IsClass)
172-
{
173-
// Array could be either registered or Type can be resolved
174-
if (type.IsArray)
175-
{
176-
return _isTypeRegistered(type) || CanResolve(type.GetElementType());
177-
}
178-
179-
// Type must be registered if:
180-
// - String
181-
// - Enumeration
182-
// - Primitive
183-
// - Abstract
184-
// - Interface
185-
// - No accessible constructor
186-
if (DelegateType.IsAssignableFrom(info) ||
187-
typeof(string) == type || info.IsEnum || info.IsPrimitive || info.IsAbstract
188-
#if NETSTANDARD1_0 || NETCOREAPP1_0
189-
|| !info.DeclaredConstructors.Any(c => !c.IsFamily && !c.IsPrivate))
190-
#else
191-
|| !type.GetTypeInfo().DeclaredConstructors.Any(c => !c.IsFamily && !c.IsPrivate))
192-
#endif
193-
return _isTypeRegistered(type);
194-
195-
return true;
196-
}
197-
198-
// Can resolve if IEnumerable or factory is registered
199-
if (info.IsGenericType)
200-
{
201-
var genericType = type.GetGenericTypeDefinition();
202-
203-
if (genericType == typeof(IEnumerable<>) || _isTypeRegistered(genericType))
204-
{
205-
return true;
206-
}
207-
}
208-
209-
// Check if Type is registered
210-
return _isTypeRegistered(type);
211-
}
212-
213155
#endregion
214156
}
215157
}

src/Processors/Methods/MethodDiagnostic.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Globalization;
43
using System.Linq;
54
using System.Linq.Expressions;
65
using System.Reflection;
76
using Unity.Builder;
8-
using Unity.Exceptions;
97
using Unity.Injection;
108
using Unity.Policy;
119
using Unity.Registration;
@@ -17,8 +15,8 @@ public class MethodDiagnostic : MethodProcessor
1715
{
1816
#region Constructors
1917

20-
public MethodDiagnostic(IPolicySet policySet)
21-
: base(policySet)
18+
public MethodDiagnostic(IPolicySet policySet, UnityContainer container)
19+
: base(policySet, container)
2220
{
2321
}
2422

src/Processors/Methods/MethodProcessor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ public class MethodProcessor : ParametersProcessor<MethodInfo>
1313
{
1414
#region Constructors
1515

16-
public MethodProcessor(IPolicySet policySet)
17-
: base(policySet, typeof(InjectionMethodAttribute))
16+
public MethodProcessor(IPolicySet policySet, UnityContainer container)
17+
: base(policySet, typeof(InjectionMethodAttribute), container)
1818
{
1919
}
2020

src/Processors/Parameters/ParametersProcessor.cs

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34
using System.Linq.Expressions;
45
using System.Reflection;
56
using Unity.Builder;
@@ -12,11 +13,21 @@ namespace Unity.Processors
1213
public abstract partial class ParametersProcessor<TMemberInfo> : MemberProcessor<TMemberInfo, object[]>
1314
where TMemberInfo : MethodBase
1415
{
16+
#region Fields
17+
18+
protected readonly UnityContainer Container;
19+
private static readonly TypeInfo DelegateType = typeof(Delegate).GetTypeInfo();
20+
21+
#endregion
22+
23+
24+
1525
#region Constructors
1626

17-
protected ParametersProcessor(IPolicySet policySet, Type attribute)
27+
protected ParametersProcessor(IPolicySet policySet, Type attribute, UnityContainer container)
1828
: base(policySet, attribute)
1929
{
30+
Container = container;
2031
}
2132

2233
#endregion
@@ -184,6 +195,71 @@ private object FromAttribute(ParameterInfo info)
184195
return info;
185196
}
186197

198+
protected bool CanResolve(ParameterInfo info)
199+
{
200+
foreach (var node in AttributeFactories)
201+
{
202+
if (null == node.Factory) continue;
203+
var attribute = info.GetCustomAttribute(node.Type);
204+
if (null == attribute) continue;
205+
206+
// If found match, use provided factory to create expression
207+
return CanResolve(info.ParameterType, node.Name(attribute));
208+
}
209+
210+
return CanResolve(info.ParameterType, null);
211+
}
212+
213+
protected bool CanResolve(Type type, string name)
214+
{
215+
#if NETSTANDARD1_0 || NETCOREAPP1_0
216+
var info = type.GetTypeInfo();
217+
#else
218+
var info = type;
219+
#endif
220+
if (info.IsClass)
221+
{
222+
// Array could be either registered or Type can be resolved
223+
if (type.IsArray)
224+
{
225+
return Container._isExplicitlyRegistered(type, name) || CanResolve(type.GetElementType(), name);
226+
}
227+
228+
// Type must be registered if:
229+
// - String
230+
// - Enumeration
231+
// - Primitive
232+
// - Abstract
233+
// - Interface
234+
// - No accessible constructor
235+
if (DelegateType.IsAssignableFrom(info) ||
236+
typeof(string) == type || info.IsEnum || info.IsPrimitive || info.IsAbstract
237+
#if NETSTANDARD1_0 || NETCOREAPP1_0
238+
|| !info.DeclaredConstructors.Any(c => !c.IsFamily && !c.IsPrivate))
239+
#else
240+
|| !type.GetTypeInfo().DeclaredConstructors.Any(c => !c.IsFamily && !c.IsPrivate))
241+
#endif
242+
return Container._isExplicitlyRegistered(type, name);
243+
244+
return true;
245+
}
246+
247+
// Can resolve if IEnumerable or factory is registered
248+
if (info.IsGenericType)
249+
{
250+
var genericType = type.GetGenericTypeDefinition();
251+
252+
if (genericType == typeof(IEnumerable<>) || Container._isExplicitlyRegistered(genericType, name))
253+
{
254+
return true;
255+
}
256+
}
257+
258+
// Check if Type is registered
259+
return Container._isExplicitlyRegistered(type, name);
260+
}
261+
262+
187263
#endregion
188264

189265

src/UnityContainer.Implementation.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public partial class UnityContainer
7070
internal ClearPolicyDelegate ClearPolicy;
7171

7272
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private Func<Type, string, IPolicySet> _get;
73-
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private Func<Type, string, bool> _isExplicitlyRegistered;
73+
[DebuggerBrowsable(DebuggerBrowsableState.Never)] internal Func<Type, string, bool> _isExplicitlyRegistered;
7474
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private Func<Type, string, Type, IPolicySet> _getGenericRegistration;
7575
[DebuggerBrowsable(DebuggerBrowsableState.Never)] internal Func<Type, bool> IsTypeExplicitlyRegistered;
7676

@@ -131,9 +131,9 @@ private UnityContainer(UnityContainer parent)
131131

132132
// Processors
133133
var fieldsProcessor = new FieldProcessor(container.Defaults);
134-
var methodsProcessor = new MethodProcessor(container.Defaults);
134+
var methodsProcessor = new MethodProcessor(container.Defaults, container);
135135
var propertiesProcessor = new PropertyProcessor(container.Defaults);
136-
var constructorProcessor = new ConstructorProcessor(container.Defaults, container.IsTypeTypeExplicitlyRegisteredRecurcive);
136+
var constructorProcessor = new ConstructorProcessor(container.Defaults, container);
137137

138138
// Processors chain
139139
container._processors = new StagedStrategyChain<MemberProcessor, BuilderStage>
@@ -168,9 +168,9 @@ internal static void SetDiagnosticPolicies(UnityContainer container)
168168

169169
// Processors
170170
var fieldsProcessor = new FieldDiagnostic(container.Defaults);
171-
var methodsProcessor = new MethodDiagnostic(container.Defaults);
171+
var methodsProcessor = new MethodDiagnostic(container.Defaults, container);
172172
var propertiesProcessor = new PropertyDiagnostic(container.Defaults);
173-
var constructorProcessor = new ConstructorDiagnostic(container.Defaults, container.IsTypeTypeExplicitlyRegisteredRecurcive);
173+
var constructorProcessor = new ConstructorDiagnostic(container.Defaults, container);
174174

175175
// Processors chain
176176
container._processors = new StagedStrategyChain<MemberProcessor, BuilderStage>

0 commit comments

Comments
 (0)