public override void ValidateAfterChildrenAdded()
        {
            base.ValidateAfterChildrenAdded();

            if (Parameters != null && Parameters.AllParameters.Any())
            {
                _constructorParameterTypes = Parameters.AllParameters.Select(x => x.ValueTypeInfo.Type).ToArray();
            }
            else
            {
                _constructorParameterTypes = new Type[0];
            }

            if (!GlobalsCoreAmbientContext.Context.CheckTypeConstructorExistence(ValueTypeInfo.Type,
                                                                                 _constructorParameterTypes,
                                                                                 out var constructorInfo, out var errorMessage))
            {
                throw new ConfigurationParseException(this, errorMessage);
            }

            if (InjectedProperties != null)
            {
                _injectedPropertiesValidator.ValidateInjectedProperties(this, ValueTypeInfo.Type,
                                                                        InjectedProperties.AllProperties, out var injectedPropertiesInfo);
            }
        }
        public override void ValidateAfterChildrenAdded()
        {
            base.ValidateAfterChildrenAdded();

            // If no constructor parameter was specified, we will be injecting by type.
            if (Parameters != null)
            {
                if (!GlobalsCoreAmbientContext.Context.CheckTypeConstructorExistence(_implementationTypeInfo.Type,
                                                                                     Parameters.AllParameters.Select(x => x.ValueTypeInfo.Type).ToArray(),
                                                                                     out var constructorInfo, out var errorMessage))
                {
                    throw new ConfigurationParseException(this, errorMessage);
                }
            }

            if (InjectedProperties != null)
            {
                _injectedPropertiesValidator.ValidateInjectedProperties(this, _implementationTypeInfo.Type,
                                                                        InjectedProperties.AllProperties, out var injectedPropertiesInfo);
            }
        }
        private object GenerateValueLocal(IConfigurationFileElement configurationFileElement, Type validBaseType, Type createdObjectType,
                                          IEnumerable <IParameterElement> constructorParameters,
                                          IEnumerable <IInjectedPropertyElement> injectedProperties)
        {
            var constructorParametersArray = constructorParameters == null ? new IParameterElement[0] : constructorParameters.ToArray();

            var parameterInfos = new ParameterInfo[constructorParametersArray.Length];

            try
            {
                for (var parameterIndex = 0; parameterIndex < constructorParametersArray.Length; ++parameterIndex)
                {
                    var parameter = constructorParametersArray[parameterIndex];

                    try
                    {
                        parameterInfos[parameterIndex] = new ParameterInfo(parameter.ValueTypeInfo.Type, parameter.GenerateValue());
                    }
                    catch (Exception e)
                    {
                        LogHelper.Context.Log.Error(e);
                        throw new ConfigurationParseException(parameter, $"Failed to generate parameter value for parameter {parameter.Name}.");
                    }
                }

                object generatedInstance;

                string errorMessage;
                if (validBaseType == null)
                {
                    generatedInstance = GlobalsCoreAmbientContext.Context.CreateInstance(createdObjectType, parameterInfos, out errorMessage);
                }
                else
                {
                    generatedInstance = GlobalsCoreAmbientContext.Context.CreateInstance(validBaseType, createdObjectType, parameterInfos, out errorMessage);
                }

                if (generatedInstance == null)
                {
                    if (errorMessage == null)
                    {
                        errorMessage = $"Failed to generate an instance of type {createdObjectType}.";
                    }

                    throw new ConfigurationParseException(configurationFileElement, errorMessage);
                }

                if (injectedProperties != null)
                {
                    var injectedPropertiesArray = injectedProperties.ToArray();

                    _injectedPropertiesValidator.ValidateInjectedProperties(configurationFileElement, createdObjectType, injectedProperties,
                                                                            out var injectedPropertyInfos);

                    for (var i = 0; i < injectedPropertiesArray.Length; ++i)
                    {
                        var injectedProperty = injectedPropertiesArray[i];

                        var propertyInfo = injectedPropertyInfos.Count <= i ? null : injectedPropertyInfos[i];

                        if (propertyInfo == null)
                        {
                            throw new ConfigurationParseException(configurationFileElement, $"Property '{createdObjectType.FullName}.{injectedProperty.Name}' was not found. This error should never happen unless something is wrong in IoC.Configuration parser.");
                        }

                        propertyInfo.SetValue(generatedInstance, injectedProperty.GenerateValue());
                    }
                }

                return(generatedInstance);
            }
            catch (Exception e) when(!(e is ConfigurationParseException))
            {
                LogHelper.Context.Log.Error(e);
                throw new ConfigurationParseException(configurationFileElement, $"Failed to generate an instance of type {createdObjectType}.");
            }
        }