33using System . Globalization ;
44using System . Linq ;
55using System . Reflection ;
6+ using Unity . Exceptions ;
67using Unity . Injection ;
78using Unity . Policy ;
89using Unity . Registration ;
@@ -113,25 +114,23 @@ public object LegacySelector(Type type, ConstructorInfo[] members)
113114 var paramLength = members [ 0 ] . GetParameters ( ) . Length ;
114115 if ( members [ 1 ] . GetParameters ( ) . Length == paramLength )
115116 {
116- throw new InvalidOperationException (
117+ return new InvalidOperationException (
117118 string . Format (
118119 CultureInfo . CurrentCulture ,
119120 "The type {0} has multiple constructors of length {1}. Unable to disambiguate." ,
120121 type . GetTypeInfo ( ) . Name ,
121- paramLength ) ) ;
122+ paramLength ) , new InvalidRegistrationException ( ) ) ;
122123 }
123124 return members [ 0 ] ;
124125 }
125126 }
126127
127- private object SmartSelector ( Type type , ConstructorInfo [ ] constructors )
128+ protected virtual object SmartSelector ( Type type , ConstructorInfo [ ] constructors )
128129 {
129130 Array . Sort ( constructors , ( a , b ) =>
130131 {
131132 var qtd = b . GetParameters ( ) . Length . CompareTo ( a . GetParameters ( ) . Length ) ;
132133
133-
134-
135134 if ( qtd == 0 )
136135 {
137136#if NETSTANDARD1_0 || NETCOREAPP1_0
@@ -145,62 +144,24 @@ private object SmartSelector(Type type, ConstructorInfo[] constructors)
145144 return qtd ;
146145 } ) ;
147146
148- int parametersCount = 0 ;
149- ConstructorInfo bestCtor = null ;
150- HashSet < Type > bestCtorParameters = null ;
151-
152147 foreach ( var ctorInfo in constructors )
153148 {
154149 var parameters = ctorInfo . GetParameters ( ) ;
155-
156- if ( null != bestCtor && parametersCount > parameters . Length ) return bestCtor ;
157- parametersCount = parameters . Length ;
158-
159150#if NET40
160151 if ( parameters . All ( p => ( null != p . DefaultValue && ! ( p . DefaultValue is DBNull ) ) || CanResolve ( p . ParameterType ) ) )
161152#else
162153 if ( parameters . All ( p => p . HasDefaultValue || CanResolve ( p . ParameterType ) ) )
163154#endif
164155 {
165- if ( bestCtor == null )
166- {
167- bestCtor = ctorInfo ;
168- }
169- else
170- {
171- // Since we're visiting constructors in decreasing order of number of parameters,
172- // we'll only see ambiguities or supersets once we've seen a 'bestConstructor'.
173-
174- if ( null == bestCtorParameters )
175- {
176- bestCtorParameters = new HashSet < Type > (
177- bestCtor . GetParameters ( ) . Select ( p => p . ParameterType ) ) ;
178- }
179-
180- if ( ! bestCtorParameters . IsSupersetOf ( parameters . Select ( p => p . ParameterType ) ) )
181- {
182- if ( bestCtorParameters . All ( p => p . GetTypeInfo ( ) . IsInterface ) &&
183- ! parameters . All ( p => p . ParameterType . GetTypeInfo ( ) . IsInterface ) )
184- return bestCtor ;
185-
186- throw new InvalidOperationException ( $ "Failed to select a constructor for { type . FullName } ") ;
187- }
188-
189- return bestCtor ;
190- }
156+ return ctorInfo ;
191157 }
192158 }
193159
194- if ( bestCtor == null )
195- {
196- throw new InvalidOperationException (
197- $ "Failed to select a constructor for { type . FullName } ") ;
198- }
199-
200- return bestCtor ;
160+ return new InvalidOperationException (
161+ $ "Failed to select a constructor for { type . FullName } ", new InvalidRegistrationException ( ) ) ;
201162 }
202163
203- private bool CanResolve ( Type type )
164+ protected bool CanResolve ( Type type )
204165 {
205166#if NETSTANDARD1_0 || NETCOREAPP1_0
206167 var info = type . GetTypeInfo ( ) ;
0 commit comments