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