Beispiel #1
0
        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);
        }
Beispiel #2
0
        /// <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));
        }