14
14
15
15
namespace Castle . Windsor . Extensions . DependencyInjection
16
16
{
17
- using Castle . MicroKernel ;
18
17
using Castle . MicroKernel . Handlers ;
19
18
using Castle . Windsor ;
20
19
using Castle . Windsor . Extensions . DependencyInjection . Scope ;
@@ -96,7 +95,6 @@ private object ResolveInstanceOrNull(Type serviceType, bool isOptional)
96
95
{
97
96
if ( container . Kernel . HasComponent ( serviceType ) )
98
97
{
99
- #if NET8_0_OR_GREATER
100
98
//this is complicated by the concept of keyed service, because if you are about to resolve WITHOUTH KEY you do not
101
99
//need to resolve keyed services. Now Keyed services are available only in version 8 but we register with an helper
102
100
//all registered services so we can know if a service was really registered with keyed service or not.
@@ -105,7 +103,7 @@ private object ResolveInstanceOrNull(Type serviceType, bool isOptional)
105
103
//now since the caller requested a NON Keyed component, we need to skip all keyed components.
106
104
var realRegistrations = componentRegistrations . Where ( x => ! x . ComponentModel . Name . StartsWith ( KeyedRegistrationHelper . KeyedRegistrationPrefix ) ) . ToList ( ) ;
107
105
string registrationName = null ;
108
- if ( realRegistrations . Count == 1 )
106
+ if ( realRegistrations . Count == 1 )
109
107
{
110
108
registrationName = realRegistrations [ 0 ] . ComponentModel . Name ;
111
109
}
@@ -116,25 +114,39 @@ private object ResolveInstanceOrNull(Type serviceType, bool isOptional)
116
114
}
117
115
else if ( realRegistrations . Count > 1 )
118
116
{
119
- //more than one component is registered for the interface without key, we have some ambiguity that is resolved, based on test
120
- //found in framework with this rule.
121
- //1. Last component win.
122
- //2. closed service are preferred over open generic.
117
+ //Need to honor IsDefault for castle registrations.
118
+ var isDefaultRegistration = realRegistrations
119
+ . FirstOrDefault ( dh => dh . ComponentModel . ExtendedProperties . Any ( ComponentIsDefault ) ) ;
123
120
124
- //take first non generic
125
- for ( int i = realRegistrations . Count - 1 ; i >= 0 ; i -- )
121
+ //Remember that castle has a specific order of resolution, if someone registered something in castle with
122
+ //IsDefault() it Must be honored.
123
+ if ( isDefaultRegistration != null )
124
+ {
125
+ registrationName = isDefaultRegistration . ComponentModel . Name ;
126
+ }
127
+ else
126
128
{
127
- if ( ! realRegistrations [ i ] . ComponentModel . Implementation . IsGenericTypeDefinition )
129
+ //more than one component is registered for the interface without key, we have some ambiguity that is resolved, based on test
130
+ //found in framework with this rule. In this situation we do not use the same rule of Castle where the first service win but
131
+ //we use the framework rule that:
132
+ //1. Last component win.
133
+ //2. closed service are preferred over open generic.
134
+
135
+ //take first non generic
136
+ for ( int i = realRegistrations . Count - 1 ; i >= 0 ; i -- )
128
137
{
129
- registrationName = realRegistrations [ i ] . ComponentModel . Name ;
130
- break ;
138
+ if ( ! realRegistrations [ i ] . ComponentModel . Implementation . IsGenericTypeDefinition )
139
+ {
140
+ registrationName = realRegistrations [ i ] . ComponentModel . Name ;
141
+ break ;
142
+ }
131
143
}
132
- }
133
144
134
- //if we did not find any non generic, take the last one.
135
- if ( registrationName == null )
136
- {
137
- registrationName = realRegistrations [ realRegistrations . Count - 1 ] . ComponentModel . Name ;
145
+ //if we did not find any non generic, take the last one.
146
+ if ( registrationName == null )
147
+ {
148
+ registrationName = realRegistrations [ realRegistrations . Count - 1 ] . ComponentModel . Name ;
149
+ }
138
150
}
139
151
}
140
152
@@ -143,10 +155,6 @@ private object ResolveInstanceOrNull(Type serviceType, bool isOptional)
143
155
return null ;
144
156
}
145
157
return container . Resolve ( registrationName , serviceType ) ;
146
- #else
147
- //no keyed component in previous framework, just resolve.
148
- return container . Resolve ( serviceType ) ;
149
- #endif
150
158
}
151
159
152
160
if ( serviceType . GetTypeInfo ( ) . IsGenericType && serviceType . GetGenericTypeDefinition ( ) == typeof ( IEnumerable < > ) )
@@ -197,6 +205,28 @@ private object ResolveInstanceOrNull(Type serviceType, bool isOptional)
197
205
return container . Resolve ( serviceType ) ;
198
206
}
199
207
208
+ private static bool ComponentIsDefault ( KeyValuePair < object , object > property )
209
+ {
210
+ if ( ! Core . Internal . Constants . DefaultComponentForServiceFilter . Equals ( property . Key ) )
211
+ {
212
+ //not the property we are looking for
213
+ return false ;
214
+ }
215
+
216
+ if ( property . Value is bool boolValue )
217
+ {
218
+ return boolValue ;
219
+ }
220
+
221
+ if ( property . Value is Predicate < Type > predicate )
222
+ {
223
+ //this is a method info that we can invoke to get the value.
224
+ return predicate ( null ) ;
225
+ }
226
+
227
+ return false ;
228
+ }
229
+
200
230
#if NET6_0_OR_GREATER
201
231
202
232
public bool IsService ( Type serviceType )
0 commit comments