예제 #1
0
        /// <summary>
        /// Copies the state of all configuration properties defined on the source component to the target component.
        /// </summary>
        /// <param name="source">The <see cref="GeneticComponent"/> from which to copy the configuration state.</param>
        /// <param name="target">The <see cref="GeneticComponent"/> to which the state is to be copied.</param>
        public static void CopyConfigurationStateTo(this GeneticComponent source, GeneticComponent target)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            BindingFlags binding = BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy;
            IEnumerable <PropertyInfo> properties = source.GetType().GetProperties(binding)
                                                    .Where(p => p.GetCustomAttribute <ConfigurationPropertyAttribute>() != null);

            foreach (PropertyInfo property in properties)
            {
                if (!property.CanRead || !property.CanWrite)
                {
                    throw new InvalidOperationException(
                              StringUtil.GetFormattedString(Resources.ErrorMsg_ConfigurationPropertyNoGetterNoSetter, source.GetType(), property.Name, typeof(ConfigurationPropertyAttribute)));
                }

                property.SetValue(target, property.GetValue(source));
            }
        }
예제 #2
0
        /// <summary>
        /// Validates the component.
        /// </summary>
        /// <param name="component">The <see cref="GeneticComponent"/> to validate.</param>
        private void Validate(GeneticComponent component)
        {
            component.Validate();

            Type currentType = component.GetType();

            while (currentType != typeof(GeneticComponent))
            {
                IEnumerable <PropertyInfo> properties = currentType
                                                        .GetProperties(BindingFlags.Public | BindingFlags.Instance);
                foreach (PropertyInfo propertyInfo in properties)
                {
                    // Check that the property is valid using the validators described by external components.
                    if (externalValidationMapping.TryGetValue(propertyInfo, out List <PropertyValidator> externalValidators))
                    {
                        object propValue = propertyInfo.GetValue(component, null);
                        foreach (PropertyValidator validator in externalValidators)
                        {
                            validator.EnsureIsValid(component.GetType().Name + Type.Delimiter + propertyInfo.Name, propValue, component);
                        }
                    }
                }

                currentType = currentType.BaseType;
            }
        }
예제 #3
0
        /// <summary>
        /// Creates a new version of the component, copies the configuration state, and initializes it.
        /// </summary>
        /// <param name="component">The component from which to create a new component and the source of the configuration state to be copied.</param>
        /// <returns>A new version of the component.</returns>
        public static GeneticComponent CreateNewAndInitialize(this GeneticComponent component)
        {
            if (component == null)
            {
                throw new ArgumentNullException(nameof(component));
            }

            GeneticComponent newComponent = component.CreateNew();

            if (newComponent == null)
            {
                throw new InvalidOperationException(
                          StringUtil.GetFormattedString(Resources.ErrorMsg_CreateNewComponentNull, component.GetType(), nameof(component.CreateNew)));
            }

            if (newComponent.GetType() != component.GetType())
            {
                throw new InvalidOperationException(
                          StringUtil.GetFormattedString(Resources.ErrorMsg_CreateNewComponentWrongType, component.GetType(), nameof(component.CreateNew), newComponent.GetType()));
            }

            component.CopyConfigurationStateTo(newComponent);

            if (newComponent is GeneticComponentWithAlgorithm newComponentWithAlg)
            {
                ((GeneticComponentWithAlgorithm)component).AssertIsInitialized();
                newComponentWithAlg.Initialize(((GeneticComponentWithAlgorithm)component).Algorithm !);
            }

            return(newComponent);
        }
예제 #4
0
        /// <summary>
        /// Compiles the mapping of component configuration properties to <see cref="PropertyValidator"/> objects as described by the specified component.
        /// </summary>
        /// <param name="component">The component to check whether it has defined validators for a configuration property.</param>
        private void CompileExternalValidatorMapping(GeneticComponent component)
        {
            if (component == null)
            {
                return;
            }

            IExternalConfigurationPropertyValidatorAttribute[] attribs = (IExternalConfigurationPropertyValidatorAttribute[])component.GetType().GetCustomAttributes(typeof(IExternalConfigurationPropertyValidatorAttribute), true);
            foreach (IExternalConfigurationPropertyValidatorAttribute attrib in attribs)
            {
                PropertyInfo prop = ExternalValidatorAttributeHelper.GetTargetPropertyInfo(attrib.TargetComponentType, attrib.TargetPropertyName);
                if (!this.externalValidationMapping.TryGetValue(prop, out List <PropertyValidator> validators))
                {
                    validators = new List <PropertyValidator>();
                    this.externalValidationMapping.Add(prop, validators);
                }
                validators.Add(attrib.Validator);
            }
        }