/// <summary> /// Check that default value object has matching type for optionProperty. /// </summary> /// <param name="optionProperty">Validated property.</param> /// <param name="requiredType">Type that is required for property value or its elements.</param> private static void checkDefaultValueMatching(PropertyInfo optionProperty, Type requiredType) { var defaultValue = ReflectionUtils.GetAttribute <OptionInfoAttribute>(optionProperty).DefaultValue; if (defaultValue == null) { //There is no default value return; } var isContainer = StructureFactory.GetContainerBuilder(optionProperty.PropertyType) != null; if (isContainer) { if (!testContainerDefault(requiredType, defaultValue)) { throw new PropertyValidationException( userMsg: "Default value for container option property '{0}' has incorrect type. Array type '" + requiredType + "[]' is required.", developerMsg: "StructureValidation::checkTypeMatching has failed due to incorrect type of default container value on property '{0}'. Array type '" + requiredType + "[]' is required.", validatedProperty: optionProperty ); } } else { if (!testAssignability(requiredType, defaultValue)) { throw new PropertyValidationException( userMsg: "Default value for option property '{0}' has incorrect type. Type '" + requiredType + "' is required.", developerMsg: "StructureValidation::checkTypeMatching has failed due to incorrect type of default value on property '{0}'. Type '" + requiredType + "' is required.", validatedProperty: optionProperty ); } } }
/// <summary> /// Check validity of structureType. If error is found, appropriate exception is thrown. /// </summary> /// <param name="structureType">Type describing validated structure.</param> internal static void ThrowOnInvalid(Type structureType) { if (structureType.GetInterfaces().Count() != 1) { throw new TypeValidationException( userMsg: "Structure type '{0}' has incorrect format, only IConfiguration interface can be implemented", developerMsg: "StructureValidation::ThrowOnInvalid failed because on structure type '{0}' was found more than IConfiguration interface implemented", validatedType: structureType ); } checkSignature(structureType, false); checkIDsValidity(StructureFactory.GetSectionProperties(structureType), StructureFactory.ResolveSectionID); checkSectionUniqueness(structureType); foreach (var sectionProperty in structureType.GetProperties()) { if (sectionProperty.GetSetMethod() != null) { throw new PropertyValidationException( userMsg: "Setter detected on section property '{0}'. Section properties cannot have setters.", developerMsg: "StructureValidation::ThrowOnInvalid failed because setter has been found on section property '{0}'", validatedProperty: sectionProperty ); } var sectionType = sectionProperty.PropertyType; checkSignature(sectionType, true); checkIDsValidity(StructureFactory.GetOptionProperties(sectionType), StructureFactory.ResolveOptionID); checkOptionUniqueness(sectionType); checkTypeMatching(sectionType); } }
/// <summary> /// Register container option, because of equality comparison. /// </summary> /// <param name="optionInfo">Option info for container option.</param> /// <param name="container">Container to be registered.</param> private void registerContainer(OptionInfo optionInfo, object container) { var containerElements = StructureFactory.GetContainerElements(container); var backup = new List <object>(containerElements); _containerBackups[optionInfo.Name] = backup; }
/// <summary> /// Check that every default value or range attribute will have data with matching type for property. /// </summary> /// <param name="sectionType">Section which properties will be checked.</param> private static void checkTypeMatching(Type sectionType) { foreach (var optionProperty in sectionType.GetProperties()) { var requiredType = StructureFactory.GetElementType(optionProperty.PropertyType); if (requiredType == null) { //property is not container, because we cant determine element type requiredType = optionProperty.PropertyType; } checkDefaultValueMatching(optionProperty, requiredType); checkRangeTypeMatching(optionProperty, requiredType); } }
/// <summary> /// Check that every option in section has unique ID. /// </summary> /// <param name="sectionType">Type describing section.</param> private static void checkOptionUniqueness(Type sectionType) { checkIDUniqueness(StructureFactory.GetOptionProperties(sectionType), StructureFactory.ResolveOptionID); }
/// <summary> /// Check that every section in structure has unique ID. /// </summary> /// <param name="structureType">Type describing structure.</param> private static void checkSectionUniqueness(Type structureType) { checkIDUniqueness(StructureFactory.GetSectionProperties(structureType), StructureFactory.ResolveSectionID); }