/// <summary> /// Gets the parameter list to call the given constructor. If a parameter could not be /// resolved, null is returned /// </summary> private object[] GetParametersFor(ConstructorInfo constructor, ComponentContainer componentContainer, Action <string> progressCallback, ComponentDescriptor[] resolveStack) { object WrapResult(object value) => value; // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local object CreateInstance(Type parameterType, string parameterName) { object Instance = componentContainer.InternalResolveInstance(parameterType, true, progressCallback, resolveStack); Instance.DbC_AssureNotNull($"Could not resolve component '{this.Descriptor.Type.FullName}' even though resolver claimed that he can. Parameter '{parameterName}' (type providing '{parameterType.FullName}' implementation) could not be instanciated"); return(Instance); } object CreateInstances(Type parameterType, string parameterName) { Array Instance = componentContainer.InternalResolveInstancesAsArray(parameterType.GetElementType(), progressCallback, resolveStack); return(Instance); } return(this.GetParametersFor(constructor, componentContainer, progressCallback, resolveStack, WrapResult, CreateInstance, CreateInstances).ToArray()); }
private IEnumerable <T> GetParametersFor <T>(ConstructorInfo constructor, ComponentContainer componentContainer, Action <string> progressCallback, ComponentDescriptor[] resolveStack, Func <object, T> wrapResult, Func <Type, string, T> createInstance, Func <Type, string, T> createInstances ) { async Task <object> CreateInstanceArrayAsync(Type parameterType) { Array Instances = await componentContainer.InternalResolveInstancesAsArrayAsync(parameterType, progressCallback, resolveStack); return(Instances); } List <T> Parameters = new List <T>(); foreach (ParameterInfo Parameter in constructor.GetParameters()) { Type ParameterType = Parameter.ParameterType; if (ComponentInstance.IsValidInterfaceReference(ParameterType)) { T Component = createInstance(ParameterType, Parameter.Name); Parameters.Add(Component); } else if (ComponentInstance.IsValidInterfaceTaskReference(ParameterType)) { object Component = ComponentInstance.DoDynamicCastAsync(ParameterType, componentContainer.InternalResolveInstanceAsync(ParameterType.GenericTypeArguments[0], true, null, new ComponentDescriptor[0])); Parameters.Add(wrapResult(Component)); } else if (ComponentInstance.IsValidFuncToInterfaceReference(ParameterType)) { LambdaExpression Lambda = Expression.Lambda( ParameterType, Expression.Convert( ((Expression <Func <object> >)(() => componentContainer.InternalResolveInstance(ParameterType.GenericTypeArguments[0], true, progressCallback, new ComponentDescriptor[0]))).Body, ParameterType.GenericTypeArguments[0])); Parameters.Add(wrapResult(Lambda.Compile())); } else if (ComponentInstance.IsValidInterfaceArrayReference(ParameterType)) { Parameters.Add(createInstances(ParameterType, Parameter.Name)); } else if (ComponentInstance.IsValidInterfaceArrayTaskReference(ParameterType)) { object Component = ComponentInstance.DoDynamicCastAsync(ParameterType, CreateInstanceArrayAsync(ParameterType.GenericTypeArguments[0].GetElementType())); Parameters.Add(wrapResult(Component)); } else if (ComponentInstance.IsValidFuncToInterfaceArrayReference(ParameterType)) { LambdaExpression Lambda = Expression.Lambda( ParameterType, Expression.Convert( ((Expression <Func <Array> >)(() => componentContainer.InternalResolveInstancesAsArray(ParameterType.GenericTypeArguments[0].GetElementType(), progressCallback, new ComponentDescriptor[0]))).Body, ParameterType.GenericTypeArguments[0])); Parameters.Add(wrapResult(Lambda.Compile())); } else if (ParameterType == typeof(ComponentRepository)) { Parameters.Add(wrapResult(this.Descriptor.PrivateRepository ?? this.Descriptor.Repository)); } else if (ParameterType == typeof(ComponentContainer)) { Parameters.Add(wrapResult(componentContainer)); } else if (ParameterType.IsAssignableFrom(this.Descriptor.ConfigType)) { Parameters.Add(wrapResult(this.Descriptor.Config)); } else { throw new InvalidOperationException("Internal error: tried to resolve constructor parameters even though the constructor wasn't adequate"); } } return(Parameters); }