private static bool ResolveType(Func <bool> isSet, ref object input, string key, CfgMetadata metadata) { if (!isSet()) { return(true); } var type = metadata.PropertyInfo.PropertyType; if (input.GetType() == type) { return(true); } var value = input; if (TryConvertValue(ref value, type)) { input = value; return(true); } metadata.TypeMismatch = true; metadata.Errors.Add(CfgEvents.TypeMismatch(key, value, type)); return(false); }
private CfgNode Process( INode node, string parent, ISerializer serializer, CfgEvents events, IDictionary <string, string> parameters, IList <ICustomizer> customizers, uint sequence, bool enabled ) { Sequence = sequence; Clear(); // preserving events, customizers, and serializer, and whether or not it's enabled Events = events; Customizers = customizers; Serializer = serializer; Enabled = enabled; LoadProperties(node, parent, parameters, customizers); LoadCollections(node, parent, parameters, sequence); if (Enabled) { PreValidate(); ValidateBasedOnAttributes(node, parameters); ValidateListsBasedOnAttributes(node.Name); Validate(); PostValidate(); } return(this); }
/// <summary> /// Constructor for injecting anything marked with IDependency /// </summary> /// <param name="dependencies"></param> protected CfgNode(params IDependency[] dependencies) { if (dependencies != null) { foreach (var dependency in dependencies.Where(dependency => dependency != null)) { if (dependency is IReader) { Reader = dependency as IReader; } else if (dependency is IParser) { Parser = dependency as IParser; } else if (dependency is ISerializer) { Serializer = dependency as ISerializer; } else if (dependency is ILogger) { var composite = new DefaultLogger(new MemoryLogger(), dependency as ILogger); if (Events == null) { Events = new CfgEvents(composite); } else { Events.Logger = composite; } } else if (dependency is IValidators) { foreach (var pair in dependency as IValidators) { Validators[pair.Key] = pair.Value; } } } } Type = GetType(); }
internal static Dictionary <string, CfgMetadata> GetMetadata(Type type) { Dictionary <string, CfgMetadata> metadata; if (MetadataCache.TryGetValue(type, out metadata)) { return(metadata); } lock (Locker) { NameCache[type] = new Dictionary <string, string>(); var keyCache = new List <string>(); var listCache = new List <string>(); #if NETS var propertyInfos = type.GetRuntimeProperties().ToArray(); #else var propertyInfos = type.GetProperties(); #endif metadata = new Dictionary <string, CfgMetadata>(StringComparer.Ordinal); foreach (var propertyInfo in propertyInfos) { if (!propertyInfo.CanRead) { continue; } if (!propertyInfo.CanWrite) { continue; } #if NETS var attribute = (CfgAttribute)propertyInfo.GetCustomAttribute(typeof(CfgAttribute), true); #else var attribute = (CfgAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(CfgAttribute), true); #endif if (attribute == null) { continue; } var key = NormalizeName(type, propertyInfo.Name); var item = new CfgMetadata(propertyInfo, attribute) { TypeDefault = GetDefaultValue(propertyInfo.PropertyType) }; // regex try { if (attribute.RegexIsSet) { #if NETS item.Regex = attribute.ignoreCase ? new Regex(attribute.regex, RegexOptions.IgnoreCase) : new Regex(attribute.regex); #else item.Regex = attribute.ignoreCase ? new Regex(attribute.regex, RegexOptions.Compiled | RegexOptions.IgnoreCase) : new Regex(attribute.regex, RegexOptions.Compiled); #endif } } catch (ArgumentException ex) { item.Errors.Add(CfgEvents.InvalidRegex(key, attribute.regex, ex)); } // check default value for type mismatch if (attribute.ValueIsSet) { if (attribute.value.GetType() != propertyInfo.PropertyType) { var value = attribute.value; if (TryConvertValue(ref value, propertyInfo.PropertyType)) { attribute.value = value; } else { item.TypeMismatch = true; item.Errors.Add(CfgEvents.TypeMismatch(key, value, propertyInfo.PropertyType)); } } } // type safety for value, min value, and max value var defaultValue = attribute.value; if (ResolveType(() => attribute.ValueIsSet, ref defaultValue, key, item)) { attribute.value = defaultValue; } var minValue = attribute.minValue; if (ResolveType(() => attribute.MinValueSet, ref minValue, key, item)) { attribute.minValue = minValue; } var maxValue = attribute.maxValue; if (ResolveType(() => attribute.MaxValueSet, ref maxValue, key, item)) { attribute.maxValue = maxValue; } //foreach (var cp in constructors) { // if (!cp.Any()) { // obj = item.ListActivator(); // break; // } // if (cp.Count() == 1) { // if (cp.First().ParameterType == typeof(int)) { // obj = Activator.CreateInstance(item.ListType, add.Attributes.Count); // break; // } // if (cp.First().ParameterType == typeof(string[])) { // var names = add.Attributes.Select(a => a.Name).ToArray(); // obj = Activator.CreateInstance(item.ListType, new object[] { names }); // break; // } // } //} #if NETS var propertyTypeInfo = propertyInfo.PropertyType.GetTypeInfo(); if (propertyTypeInfo.IsGenericType) { listCache.Add(key); item.ListType = propertyTypeInfo.GenericTypeArguments[0]; var listTypeInfo = item.ListType.GetTypeInfo(); item.ImplementsProperties = typeof(IProperties).GetTypeInfo().IsAssignableFrom(listTypeInfo); item.Constructors = propertyTypeInfo.DeclaredConstructors.Select(c => c.GetParameters()); item.ListActivator = () => Activator.CreateInstance(propertyInfo.PropertyType); if (listTypeInfo.IsSubclassOf(typeof(CfgNode))) { item.Loader = () => (CfgNode)Activator.CreateInstance(item.ListType); } } else { keyCache.Add(key); } #else if (propertyInfo.PropertyType.IsGenericType) { listCache.Add(key); item.ListType = propertyInfo.PropertyType.GetGenericArguments()[0]; item.ImplementsProperties = typeof(IProperties).IsAssignableFrom(item.ListType); item.Constructors = item.ListType.GetConstructors().Select(c => c.GetParameters()); item.ListActivator = () => Activator.CreateInstance(propertyInfo.PropertyType); if (item.ListType.IsSubclassOf(typeof(CfgNode))) { item.Loader = () => (CfgNode)Activator.CreateInstance(item.ListType); } } else { keyCache.Add(key); } #endif if (string.IsNullOrEmpty(attribute.name)) { attribute.name = key; } item.Setter = CfgReflectionHelper.CreateSetter(propertyInfo); item.Getter = CfgReflectionHelper.CreateGetter(propertyInfo); metadata[key] = item; } PropertyCache[type] = keyCache; ElementCache[type] = listCache; MetadataCache[type] = metadata; return(metadata); } }
protected CfgNode() { Events = new CfgEvents(new DefaultLogger(new MemoryLogger())); Clear(); Type = GetType(); }
CfgNode Load( INode node, string parent, ISerializer serializer, CfgEvents events, IDictionary<string, IValidator> validators, ShorthandRoot shorthand, Dictionary<string, string> parameters ) { this.Clear(events); Shorthand = shorthand; Validators = validators; Serializer = serializer; LoadProperties(node, parent, parameters); LoadCollections(node, parent, parameters); PreValidate(); ValidateBasedOnAttributes(); ValidateListsBasedOnAttributes(node.Name); Validate(); PostValidate(); return this; }