Skip to content

Commit f0b3b96

Browse files
committed
Refactored code to remove copy/paste.
1 parent 636dd75 commit f0b3b96

1 file changed

Lines changed: 61 additions & 58 deletions

File tree

src/Autofac/Features/Collections/CollectionRegistrationSource.cs

Lines changed: 61 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -119,65 +119,12 @@ public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Fun
119119
limitType,
120120
(c, p) =>
121121
{
122-
if (isAnyKeyQuery)
123-
{
124-
// AnyKey queries for collections return _all_ explicitly
125-
// keyed services. (Services _registered_ with AnyKey are
126-
// intentionally excluded, however, since they are
127-
// effectively "default" registrations and would be
128-
// duplicated in the output if included alongside their
129-
// explicitly keyed counterparts.)
130-
//
131-
// We must resolve each element using the concrete keyed
132-
// service so the KeyedServiceParameterInjector can flow
133-
// that key into [ServiceKey] parameters.
134-
var keyedRegistrations = GetAllSpecificKeyedRegistrations(c.ComponentRegistry, elementType);
135-
var output = factory(keyedRegistrations.Count);
136-
var isFixedSize = output.IsFixedSize;
137-
138-
for (var i = 0; i < keyedRegistrations.Count; i++)
139-
{
140-
var (keyedService, itemRegistration) = keyedRegistrations[i];
141-
var resolveRequest = new ResolveRequest(keyedService, itemRegistration, p);
142-
var component = c.ResolveComponent(resolveRequest);
143-
if (isFixedSize)
144-
{
145-
output[i] = component;
146-
}
147-
else
148-
{
149-
output.Add(component);
150-
}
151-
}
152-
153-
return output;
154-
}
155-
156-
var itemRegistrations = c.ComponentRegistry
157-
.ServiceRegistrationsFor(elementTypeService)
158-
.Where(cr => !cr.Registration.Options.HasOption(RegistrationOptions.ExcludeFromCollections))
159-
.OrderBy(cr => cr.Registration.GetRegistrationOrder())
160-
.ToList();
161-
162-
var defaultOutput = factory(itemRegistrations.Count);
163-
var defaultOutputIsFixedSize = defaultOutput.IsFixedSize;
164-
165-
for (var i = 0; i < itemRegistrations.Count; i++)
166-
{
167-
var itemRegistration = itemRegistrations[i];
168-
var resolveRequest = new ResolveRequest(elementTypeService, itemRegistration, p);
169-
var component = c.ResolveComponent(resolveRequest);
170-
if (defaultOutputIsFixedSize)
171-
{
172-
defaultOutput[i] = component;
173-
}
174-
else
175-
{
176-
defaultOutput.Add(component);
177-
}
178-
}
122+
var registrationTuples = isAnyKeyQuery
123+
? GetAllSpecificKeyedRegistrations(c.ComponentRegistry, elementType)
124+
.ConvertAll(static tuple => ((Service)tuple.KeyedService, tuple.Registration))
125+
: BuildStandardRegistrationList(c.ComponentRegistry, elementTypeService);
179126

180-
return defaultOutput;
127+
return BuildCollection(c, factory, registrationTuples, p);
181128
});
182129

183130
var registration = new ComponentRegistration(
@@ -214,6 +161,24 @@ private static Func<int, IList> GenerateArrayFactory(Type elementType)
214161
return Expression.Lambda<Func<int, IList>>(newArray, parameter).Compile();
215162
}
216163

164+
/// <summary>
165+
/// When the query is for "any keyed" enumerable, we need to find all the
166+
/// specific keyed registrations and return them.
167+
/// </summary>
168+
/// <param name="registry">
169+
/// The registry to search for registrations. We need to search the entire
170+
/// registry because "any keyed" could match any specific key.
171+
/// </param>
172+
/// <param name="elementType">
173+
/// The element type of the enumerable being resolved. We need this to
174+
/// filter the registry down to only the relevant registrations.
175+
/// </param>
176+
/// <returns>
177+
/// A list of tuples containing the specific keyed service and the
178+
/// registration for each matching registration. We return the specific
179+
/// keyed service so that we can issue resolve requests that still know the
180+
/// original key.
181+
/// </returns>
217182
private static List<(KeyedService KeyedService, ServiceRegistration Registration)> GetAllSpecificKeyedRegistrations(IComponentRegistry registry, Type elementType)
218183
{
219184
var result = new List<(KeyedService, ServiceRegistration)>();
@@ -257,4 +222,42 @@ private static Func<int, IList> GenerateArrayFactory(Type elementType)
257222
.OrderBy(tuple => tuple.Item2.Registration.GetRegistrationOrder())
258223
.ToList();
259224
}
225+
226+
private static List<(Service Service, ServiceRegistration Registration)> BuildStandardRegistrationList(IComponentRegistry registry, Service elementTypeService)
227+
{
228+
return registry
229+
.ServiceRegistrationsFor(elementTypeService)
230+
.Where(cr => !cr.Registration.Options.HasOption(RegistrationOptions.ExcludeFromCollections))
231+
.OrderBy(cr => cr.Registration.GetRegistrationOrder())
232+
.Select(cr => ((Service)elementTypeService, cr))
233+
.ToList();
234+
}
235+
236+
private static IList BuildCollection(
237+
IComponentContext context,
238+
Func<int, IList> factory,
239+
List<(Service Service, ServiceRegistration Registration)> registrations,
240+
IEnumerable<Parameter> parameters)
241+
{
242+
var output = factory(registrations.Count);
243+
var isFixedSize = output.IsFixedSize;
244+
245+
for (var i = 0; i < registrations.Count; i++)
246+
{
247+
var (service, registration) = registrations[i];
248+
var resolveRequest = new ResolveRequest(service, registration, parameters);
249+
var component = context.ResolveComponent(resolveRequest);
250+
251+
if (isFixedSize)
252+
{
253+
output[i] = component;
254+
}
255+
else
256+
{
257+
output.Add(component);
258+
}
259+
}
260+
261+
return output;
262+
}
260263
}

0 commit comments

Comments
 (0)