11// Copyright (c) Autofac Project. All rights reserved.
22// Licensed under the MIT License. See LICENSE in the project root for license information.
33
4- using System . Collections ;
5- using System . Reflection ;
6-
74namespace Autofac . Core ;
85
96/// <summary>
107/// Helper methods for ensuring keyed resolve requests carry the requested key as a parameter.
118/// </summary>
12- internal static partial class KeyedServiceParameterInjector
9+ internal static class KeyedServiceParameterInjector
1310{
1411 /// <summary>
1512 /// Ensures keyed service requests carry their associated key with the parameter sequence.
@@ -29,7 +26,7 @@ public static IEnumerable<Parameter> AddKeyedServiceParameter(Service service, I
2926 return parameters ?? throw new ArgumentNullException ( nameof ( parameters ) ) ;
3027 }
3128
32- return EnsureKeyedServiceParameter ( keyedService . ServiceKey , parameters ) ;
29+ return AddKeyedServiceParameter ( keyedService . ServiceKey , parameters ) ;
3330 }
3431
3532 /// <summary>
@@ -38,7 +35,7 @@ public static IEnumerable<Parameter> AddKeyedServiceParameter(Service service, I
3835 /// <param name="serviceKey">The keyed service key.</param>
3936 /// <param name="parameters">The parameters supplied by the caller.</param>
4037 /// <returns>An enumerable that exposes the keyed service key when appropriate.</returns>
41- public static IEnumerable < Parameter > EnsureKeyedServiceParameter ( object serviceKey , IEnumerable < Parameter > parameters )
38+ public static IEnumerable < Parameter > AddKeyedServiceParameter ( object serviceKey , IEnumerable < Parameter > parameters )
4239 {
4340 if ( serviceKey == null )
4441 {
@@ -50,19 +47,12 @@ public static IEnumerable<Parameter> EnsureKeyedServiceParameter(object serviceK
5047 throw new ArgumentNullException ( nameof ( parameters ) ) ;
5148 }
5249
53- if ( KeyedService . IsAnyKey ( serviceKey ) )
50+ if ( KeyedService . IsAnyKey ( serviceKey ) || HasKeyParameter ( parameters , serviceKey ) )
5451 {
5552 return parameters ;
5653 }
5754
58- if ( parameters is IKeyedServiceKeyAccessor accessor &&
59- accessor . TryGetServiceKey ( out var existingKey ) &&
60- Equals ( existingKey , serviceKey ) )
61- {
62- return parameters ;
63- }
64-
65- return new KeyedServiceParameterCollection ( parameters , serviceKey ) ;
55+ return AppendKeyParameter ( parameters , serviceKey ) ;
6656 }
6757
6858 /// <summary>
@@ -72,72 +62,24 @@ public static IEnumerable<Parameter> EnsureKeyedServiceParameter(object serviceK
7262 /// <returns>A parameter capable of supplying the keyed service key, or null if not available.</returns>
7363 public static Parameter ? TryCreateConstructorParameter ( IEnumerable < Parameter > parameters )
7464 {
75- if ( parameters is IKeyedServiceKeyAccessor accessor &&
76- accessor . TryGetServiceKey ( out var key ) )
77- {
78- return new KeyedServiceConstructorParameter ( key ) ;
79- }
80-
81- return null ;
65+ return parameters ?
66+ . OfType < KeyedServiceKeyParameter > ( )
67+ . FirstOrDefault ( ) ?
68+ . ForConstructorInjection ( ) ;
8269 }
8370
84- /// <summary>
85- /// Wraps a set of parameters with an associated keyed service key.
86- /// </summary>
87- private sealed class KeyedServiceParameterCollection : IEnumerable < Parameter > , IKeyedServiceKeyAccessor
88- {
89- private readonly IEnumerable < Parameter > _source ;
90- private readonly object _key ;
91-
92- public KeyedServiceParameterCollection ( IEnumerable < Parameter > source , object key )
93- {
94- _source = source ?? throw new ArgumentNullException ( nameof ( source ) ) ;
95- _key = key ?? throw new ArgumentNullException ( nameof ( key ) ) ;
96- }
71+ private static bool HasKeyParameter ( IEnumerable < Parameter > parameters , object serviceKey )
72+ => parameters . OfType < KeyedServiceKeyParameter > ( ) . Any ( p => Equals ( p . ServiceKey , serviceKey ) ) ;
9773
98- public IEnumerator < Parameter > GetEnumerator ( ) => _source . GetEnumerator ( ) ;
99-
100- IEnumerator IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
101-
102- public bool TryGetServiceKey ( [ NotNullWhen ( returnValue : true ) ] out object ? key )
103- {
104- key = _key ;
105- return true ;
106- }
107- }
108-
109- /// <summary>
110- /// Supplies the keyed service key value to constructor parameters when matching by type.
111- /// </summary>
112- private sealed class KeyedServiceConstructorParameter : Parameter
74+ private static IEnumerable < Parameter > AppendKeyParameter ( IEnumerable < Parameter > parameters , object serviceKey )
11375 {
114- private readonly object _key ;
76+ var keyParameter = new KeyedServiceKeyParameter ( serviceKey ) ;
11577
116- public KeyedServiceConstructorParameter ( object key )
78+ if ( ReferenceEquals ( parameters , ResolveRequest . NoParameters ) )
11779 {
118- _key = key ?? throw new ArgumentNullException ( nameof ( key ) ) ;
80+ return new Parameter [ ] { keyParameter } ;
11981 }
12082
121- public override bool CanSupplyValue ( ParameterInfo pi , IComponentContext context , [ NotNullWhen ( returnValue : true ) ] out Func < object ? > ? valueProvider )
122- {
123- if ( pi == null )
124- {
125- throw new ArgumentNullException ( nameof ( pi ) ) ;
126- }
127-
128- if ( context == null )
129- {
130- throw new ArgumentNullException ( nameof ( context ) ) ;
131- }
132-
133- if ( pi . ParameterType . IsAssignableFrom ( _key . GetType ( ) ) )
134- {
135- valueProvider = ( ) => _key ;
136- return true ;
137- }
138-
139- valueProvider = null ;
140- return false ;
141- }
83+ return parameters . Append ( keyParameter ) ;
14284 }
14385}
0 commit comments