private BoundConstructor[] GetAllBindings(ConstructorBinder[] availableConstructors, IResolveContext context, IEnumerable <Parameter> parameters) { // Most often, there will be no `parameters` and/or no `_defaultParameters`; in both of those cases we can avoid allocating. var prioritisedParameters = parameters.Any() ? EnumerateParameters(parameters) : _defaultParameters; var boundConstructors = new BoundConstructor[availableConstructors.Length]; var validBindings = availableConstructors.Length; for (var idx = 0; idx < availableConstructors.Length; idx++) { var bound = availableConstructors[idx].Bind(prioritisedParameters, context); boundConstructors[idx] = bound; if (!bound.CanInstantiate) { validBindings--; } } if (validBindings == 0) { throw new DependencyResolutionException(GetBindingFailureMessage(boundConstructors)); } return(boundConstructors); }
/// <summary> /// Binds the set of parameters to the constructor. <see cref="BoundConstructor.CanInstantiate"/> indicates success. /// </summary> /// <param name="availableParameters">The set of all parameters.</param> /// <param name="context">The current component context.</param> /// <returns>The bind result.</returns> public BoundConstructor Bind(IEnumerable <Parameter> availableParameters, IResolveContext context) { if (availableParameters is null) { throw new ArgumentNullException(nameof(availableParameters)); } if (context is null) { throw new ArgumentNullException(nameof(context)); } var constructorArgs = _constructorArgs; var constructorArgLength = constructorArgs.Length; if (constructorArgLength == 0) { // No args, auto-bind with an empty value-retriever array to avoid the allocation. return(BoundConstructor.ForBindSuccess(this, _factory !, Array.Empty <Func <object?> >())); } if (_illegalParameter is object) { return(BoundConstructor.ForBindFailure(this, _illegalParameter)); } var valueRetrievers = new Func <object?> [constructorArgLength]; for (var idx = 0; idx < constructorArgLength; idx++) { var pi = constructorArgs[idx]; var foundValue = false; foreach (var param in availableParameters) { if (param.CanSupplyValue(pi, context, out var valueRetriever)) { valueRetrievers[idx] = valueRetriever; foundValue = true; break; } } if (!foundValue) { return(BoundConstructor.ForBindFailure(this, pi)); } } return(BoundConstructor.ForBindSuccess(this, _factory !, valueRetrievers)); }