11using System ;
2+ using System . Collections . Generic ;
23using System . Linq ;
34using System . Reflection ;
45using Microsoft . Extensions . DependencyInjection ;
56using Ninject . Activation ;
7+ using Ninject . Parameters ;
68using Ninject . Planning . Bindings ;
79using Ninject . Planning . Targets ;
810using Ninject . Web . AspNetCore . Parameters ;
@@ -32,102 +34,90 @@ public override bool HasDefaultValue
3234 }
3335 }
3436
35- protected override Func < IBindingMetadata , bool > ReadConstraintFromTarget ( )
37+ /// <summary>
38+ /// MethodInjectionStrategy.GetMethodArguments calls ITarget.ResolveWithin.
39+ /// As we can't override the base implementation as it is not virtual, the
40+ /// explicit interface implementation helps to still delegate the resolution to here.
41+ /// </summary>
42+ object ITarget . ResolveWithin ( IContext parent )
3643 {
3744#if NET8_0_OR_GREATER
38- var keyedattributes = GetCustomAttributes ( typeof ( FromKeyedServicesAttribute ) , true ) as FromKeyedServicesAttribute [ ] ;
39- var baseFunc = base . ReadConstraintFromTarget ( ) ;
40- if ( keyedattributes == null || keyedattributes . Length == 0
41- #if NET10_0_OR_GREATER
42- || ( keyedattributes [ 0 ] . LookupMode == ServiceKeyLookupMode . NullKey )
43- #endif
44- )
45+ var serviceKeyAttributes = GetCustomAttributes ( typeof ( ServiceKeyAttribute ) , true ) as ServiceKeyAttribute [ ] ;
46+ if ( serviceKeyAttributes ? . Length > 0 )
4547 {
46- return baseFunc ;
48+ return ResolveServiceKeyValue ( parent ) ;
4749 }
4850
49- return metadata =>
51+ var keyedattributes = GetCustomAttributes ( typeof ( FromKeyedServicesAttribute ) , true ) as FromKeyedServicesAttribute [ ] ;
52+ if ( keyedattributes ? . Length > 0 )
5053 {
51- var result = true ;
52- if ( baseFunc != null )
53- {
54- result = baseFunc ( metadata ) ;
55- }
56-
57- if ( metadata . HasServiceKeyMetadata ( ) )
58- {
59- object keyToCompareWith = keyedattributes [ 0 ] . Key ;
60- #if NET10_0_OR_GREATER
61- if ( keyedattributes [ 0 ] . LookupMode == ServiceKeyLookupMode . InheritKey ) {
62- // here we would need the request!
63- }
54+ return ResolveFromKeyedService ( parent , keyedattributes [ 0 ] ) ;
55+ }
6456#endif
65- result = result && metadata . DoesMetadataMatchServiceKey ( keyToCompareWith ) ;
66- }
67- else
68- {
69- // we can't match bindings here which don't have a servicekey. If FromKeyServiceAttribute is present
70- // the match fails if no servicekey available.
71- result = false ;
72- }
57+ return base . ResolveWithin ( parent ) ;
58+ }
7359
74- return result ;
75- } ;
76- #else
77- return base . ReadConstraintFromTarget ( ) ;
60+ #if NET8_0_OR_GREATER
61+ private object ResolveFromKeyedService ( IContext parent , FromKeyedServicesAttribute keyedattribute )
62+ {
63+ var fromKeyedServiceValue = DeterimeFromKeyedServiceValue ( keyedattribute , parent . Parameters ) ;
64+ var additionalConstraint = fromKeyedServiceValue != null
65+ ? metadata => metadata . DoesMetadataMatchServiceKey ( fromKeyedServiceValue )
66+ : ( Func < IBindingMetadata , bool > ) null ;
67+ var child = parent . Request . CreateKeyedChildRequest ( Type , fromKeyedServiceValue , parent , this , additionalConstraint ) ;
68+ child . IsUnique = true ;
69+ return parent . Kernel . Resolve ( child ) . SingleOrDefault ( ) ;
70+ }
71+
72+ private object DeterimeFromKeyedServiceValue (
73+ FromKeyedServicesAttribute keyedattribute , ICollection < IParameter > parameters )
74+ {
75+ #if NET10_0_OR_GREATER
76+ if ( keyedattribute . LookupMode == ServiceKeyLookupMode . NullKey )
77+ {
78+ // means no constraint, resolve normally.
79+ return null ;
80+ }
81+ if ( keyedattribute . LookupMode == ServiceKeyLookupMode . InheritKey )
82+ {
83+ var serviceKeyParam = parameters . LastOrDefault ( x => x is ServiceKeyParameter ) as ServiceKeyParameter ;
84+ return serviceKeyParam ? . ServiceKey ;
85+ }
7886#endif
87+ return keyedattribute . Key ;
7988 }
8089
81- /// <summary>
82- /// MethodInjectionStrategy.GetMethodArguments calls ITarget.ResolveWithin.
83- /// As we can't override the base implementation as it is not virtual, the
84- /// explicit interface implementation helps to still delegate the resolution to here.
85- /// </summary>
86- object ITarget . ResolveWithin ( IContext parent )
90+ private object ResolveServiceKeyValue ( IContext parent )
8791 {
88- #if NET8_0_OR_GREATER
89- var serviceKeyAttributes = GetCustomAttributes ( typeof ( ServiceKeyAttribute ) , true ) as ServiceKeyAttribute [ ] ;
90- if ( serviceKeyAttributes ? . Length > 0 )
92+ var result = parent . Binding . Metadata . GetServiceKey ( ) ;
93+ var serviceKeyParameter = parent . Parameters . LastOrDefault ( x => x is ServiceKeyParameter ) as ServiceKeyParameter ;
94+ if ( serviceKeyParameter != null )
9195 {
92- var result = parent . Binding . Metadata . GetServiceKey ( ) ;
93- var serviceKeyParameter = parent . Parameters . LastOrDefault ( x => x is ServiceKeyParameter ) as ServiceKeyParameter ;
94- if ( serviceKeyParameter != null )
95- {
96- result = serviceKeyParameter . ServiceKey ;
97- }
96+ result = serviceKeyParameter . ServiceKey ;
97+ }
9898
99- var asConvertible = result as IConvertible ;
100- if ( asConvertible != null )
99+ var asConvertible = result as IConvertible ;
100+ if ( asConvertible != null )
101+ {
102+ try
101103 {
102- try
103- {
104- result = Convert . ChangeType ( asConvertible , this . Type ) ;
105- }
106- catch ( InvalidCastException )
107- {
108- // we have to throw and InvalidOperationException in this case, a InvalidCastException
109- // is not passing the tests
110- throw new InvalidOperationException ( "Cannot convert " + asConvertible + " to " + this . Type ) ;
111- }
104+ result = Convert . ChangeType ( asConvertible , this . Type ) ;
112105 }
113-
114- if ( result != null && ! this . Type . IsAssignableFrom ( result . GetType ( ) ) )
106+ catch ( InvalidCastException )
115107 {
116- throw new InvalidOperationException ( "Cannot convert " + result + " to " + this . Type ) ;
108+ // we have to throw and InvalidOperationException in this case, a InvalidCastException
109+ // is not passing the tests
110+ throw new InvalidOperationException ( "Cannot convert " + asConvertible + " to " + this . Type ) ;
117111 }
118-
119- return result ;
120112 }
121113
122- var keyedattributes = GetCustomAttributes ( typeof ( FromKeyedServicesAttribute ) , true ) as FromKeyedServicesAttribute [ ] ;
123- if ( keyedattributes ? . Length > 0 )
114+ if ( result != null && ! this . Type . IsAssignableFrom ( result . GetType ( ) ) )
124115 {
125- var child = parent . Request . CreateKeyedChildRequest ( Type , keyedattributes [ 0 ] . Key , parent , this ) ;
126- child . IsUnique = true ;
127- return parent . Kernel . Resolve ( child ) . SingleOrDefault ( ) ;
116+ throw new InvalidOperationException ( "Cannot convert " + result + " to " + this . Type ) ;
128117 }
129- #endif
130- return base . ResolveWithin ( parent ) ;
118+
119+ return result ;
131120 }
121+ #endif
132122 }
133123}
0 commit comments