/// <summary> /// Selects the best constructor from the available constructors. /// </summary> /// <param name="constructorBindings">Available constructors.</param> /// <returns>The best constructor.</returns> /// <exception cref='DependencyResolutionException'>A single unambiguous match could not be chosen.</exception> public ConstructorParameterBinding SelectConstructorBinding(ConstructorParameterBinding[] constructorBindings) { if (constructorBindings == null) throw new ArgumentNullException("constructorBindings"); if (constructorBindings.Length == 0) throw new ArgumentOutOfRangeException("constructorBindings"); if (constructorBindings.Length == 1) return constructorBindings[0]; var withLength = constructorBindings .Select(binding => new { Binding = binding, ConstructorParameterLength = binding.TargetConstructor.GetParameters().Length }); var maxLength = withLength.Max(binding => binding.ConstructorParameterLength); var maximal = withLength .Where(binding => binding.ConstructorParameterLength == maxLength) .Select(ctor => ctor.Binding) .ToArray(); if (maximal.Length == 1) return maximal[0]; throw new DependencyResolutionException(string.Format( CultureInfo.CurrentCulture, MostParametersConstructorSelectorResources.UnableToChooseFromMultipleConstructors, maxLength, maximal[0].TargetConstructor.DeclaringType)); }
/// <summary> /// Selects the best constructor from the available constructors. /// </summary> /// <param name="constructorBindings">Available constructors.</param> /// <returns>The best constructor.</returns> /// <exception cref='DependencyResolutionException'>A single unambiguous match could not be chosen.</exception> public ConstructorParameterBinding SelectConstructorBinding(ConstructorParameterBinding[] constructorBindings) { if (constructorBindings == null) throw new ArgumentNullException("constructorBindings"); if (constructorBindings.Length == 0) throw new ArgumentOutOfRangeException("constructorBindings"); if (constructorBindings.Length == 1) return constructorBindings[0]; var withLength = constructorBindings .Select(binding => new { Binding = binding, ConstructorParameterLength = binding.TargetConstructor.GetParameters().Length }); var maxLength = withLength.Max(binding => binding.ConstructorParameterLength); var maximal = withLength .Where(binding => binding.ConstructorParameterLength == maxLength) .Select(ctor => ctor.Binding) .ToArray(); if (maximal.Length == 1) return maximal[0]; throw new DependencyResolutionException(string.Format( "Cannot choose between multiple constructors with equal length {0} on type '{1}'. Select the constructor explicitly, with the UsingConstructor() configuration method, when the component is registered.", maxLength, maximal[0].TargetConstructor.DeclaringType)); }
public void WhenAnExceptionIsThrownFromAConstructor_TheInnerExceptionIsWrapped() { var ci = typeof(ThrowsInCtor).GetTypeInfo().DeclaredConstructors.Single(); var cpb = new ConstructorParameterBinding( ci, Enumerable.Empty<Parameter>(), new ContainerBuilder().Build()); var dx = Assert.Throws<DependencyResolutionException>(() => cpb.Instantiate()); Assert.True(dx.Message.Contains(typeof(ThrowsInCtor).Name)); Assert.Equal(ThrowsInCtor.Message, dx.InnerException.Message); }
/// <summary> /// Selects the best constructor from the available constructors. /// </summary> /// <param name="constructorBindings">Available constructors.</param> /// <returns>The best constructor.</returns> public ConstructorParameterBinding SelectConstructorBinding(ConstructorParameterBinding[] constructorBindings) { if (constructorBindings == null) throw new ArgumentNullException("constructorBindings"); var result = constructorBindings .Where(b => b.TargetConstructor.GetParameters().Select(p => p.ParameterType).SequenceEqual(_signature)) .ToArray(); if (result.Length == 1) return result[0]; if (!constructorBindings.Any()) throw new ArgumentException(MatchingSignatureConstructorSelectorResources.AtLeastOneBindingRequired); var targetTypeName = constructorBindings.First().TargetConstructor.DeclaringType.Name; var signature = string.Join(", ", _signature.Select(t => t.Name).ToArray()); if (result.Length == 0) throw new DependencyResolutionException(string.Format(CultureInfo.CurrentCulture, MatchingSignatureConstructorSelectorResources.RequiredConstructorNotAvailable, targetTypeName, signature)); throw new DependencyResolutionException(string.Format(CultureInfo.CurrentCulture, MatchingSignatureConstructorSelectorResources.TooManyConstructorsMatch, signature)); }
private ConstructorParameterBinding[] GetValidConstructorBindings(IComponentContext 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() ? (_defaultParameters.Length == 0 ? parameters : parameters.Concat(_defaultParameters)) : _defaultParameters; var constructorBindings = new ConstructorParameterBinding[_availableConstructors.Length]; for (var i = 0; i < _availableConstructors.Length; ++i) { constructorBindings[i] = new ConstructorParameterBinding(_availableConstructors[i], prioritisedParameters, context); } // Copy-on-write; 99% of components will have a single constructor that can be instantiated. var validBindings = constructorBindings; for (var i = 0; i < constructorBindings.Length; ++i) { if (!constructorBindings[i].CanInstantiate) { // Further optimisation opportunity here validBindings = constructorBindings .Where(cb => cb.CanInstantiate) .ToArray(); break; } } if (validBindings.Length == 0) { throw new DependencyResolutionException(GetBindingFailureMessage(constructorBindings)); } return(validBindings); }
public ConstructorParameterBinding SelectConstructorBinding(ConstructorParameterBinding[] constructorBindings) { return null; }
/// <summary> /// Selects the best constructor from the available constructors. /// </summary> /// <param name="constructorBindings">Available constructors.</param> /// <returns> /// The best constructor. /// </returns> public ConstructorParameterBinding SelectConstructorBinding(ConstructorParameterBinding[] constructorBindings) { return constructorBindings.First(); }