/// <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)); } }
/// <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; } }
/// <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); }
/// <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); } }