private static void ScanProperties <T>(List <T> result, object o, int level, Dictionary <object, int> visitedObjects) where T : class { if (o == null) { return; } if (!o.GetType().IsDefined(typeof(NLogConfigurationItemAttribute), true)) { return; } if (visitedObjects.ContainsKey(o)) { return; } visitedObjects.Add(o, 0); var t = o as T; if (t != null) { result.Add(t); } if (InternalLogger.IsTraceEnabled) { InternalLogger.Trace("{0}Scanning {1} '{2}'", new string(' ', level), o.GetType().Name, o); } foreach (PropertyInfo prop in PropertyHelper.GetAllReadableProperties(o.GetType())) { if (prop.PropertyType.IsPrimitive || prop.PropertyType.IsEnum || prop.PropertyType == typeof(string)) { continue; } object value = prop.GetValue(o, null); if (value == null) { continue; } var enumerable = value as IEnumerable; if (enumerable != null) { foreach (object element in enumerable.OfType <object>().ToList()) { ScanProperties(result, element, level + 1, visitedObjects); } } else { ScanProperties(result, value, level + 1, visitedObjects); } } }
/// <remarks>ISet is not there in .net35, so using HashSet</remarks> private static void ScanProperties <T>(bool aggressiveSearch, List <T> result, object o, int level, HashSet <object> visitedObjects) where T : class { if (o == null) { return; } var type = o.GetType(); try { if (type == null || !type.IsDefined(typeof(NLogConfigurationItemAttribute), true)) { return; } } catch (System.Exception ex) { InternalLogger.Info(ex, "{0}Type reflection not possible for: {1}. Maybe because of .NET Native.", new string(' ', level), o.ToString()); return; } if (visitedObjects.Contains(o)) { return; } visitedObjects.Add(o); if (InternalLogger.IsTraceEnabled) { InternalLogger.Trace("{0}Scanning {1} '{2}'", new string(' ', level), type.Name, o); } if (o is T t) { result.Add(t); if (!aggressiveSearch) { return; } } foreach (PropertyInfo prop in PropertyHelper.GetAllReadableProperties(type)) { var propValue = GetConfigurationPropertyValue(o, prop, level); if (propValue == null) { continue; } ScanPropertyForObject(prop, propValue, aggressiveSearch, result, level, visitedObjects); } }
internal static void CheckRequiredParameters(object o) { foreach (PropertyInfo propInfo in PropertyHelper.GetAllReadableProperties(o.GetType())) { if (propInfo.IsDefined(typeof(RequiredParameterAttribute), false)) { object value = propInfo.GetValue(o, null); if (value == null) { throw new NLogConfigurationException( "Required parameter '" + propInfo.Name + "' on '" + o + "' was not specified."); } } } }
/// <remarks>ISet is not there in .net35, so using HashSet</remarks> private static void ScanProperties <T>(bool aggressiveSearch, List <T> result, object o, int level, HashSet <object> visitedObjects) where T : class { if (o == null) { return; } if (visitedObjects.Contains(o)) { return; } var type = o.GetType(); if (!IncludeConfigurationItem(o, type, level)) { return; } if (InternalLogger.IsTraceEnabled) { InternalLogger.Trace("{0}Scanning {1} '{2}'", new string(' ', level), type.Name, o); } if (o is T t) { result.Add(t); if (!aggressiveSearch) { return; } } foreach (PropertyInfo prop in PropertyHelper.GetAllReadableProperties(type)) { var propValue = GetConfigurationPropertyValue(o, prop, level); if (propValue == null) { continue; } visitedObjects.Add(o); ScanPropertyForObject(prop, propValue, aggressiveSearch, result, level, visitedObjects); } }
/// <remarks>ISet is not there in .net35, so using HashSet</remarks> private static void ScanProperties <T>(List <T> result, object o, int level, HashSet <object> visitedObjects) where T : class { if (o == null) { return; } var type = o.GetType(); if (!type.IsDefined(typeof(NLogConfigurationItemAttribute), true)) { return; } if (visitedObjects.Contains(o)) { return; } visitedObjects.Add(o); var t = o as T; if (t != null) { result.Add(t); } if (InternalLogger.IsTraceEnabled) { InternalLogger.Trace("{0}Scanning {1} '{2}'", new string(' ', level), type.Name, o); } foreach (PropertyInfo prop in PropertyHelper.GetAllReadableProperties(type)) { if (prop.PropertyType.IsPrimitive || prop.PropertyType.IsEnum || prop.PropertyType == typeof(string) || prop.IsDefined(typeof(NLogConfigurationIgnorePropertyAttribute), true)) { continue; } object value = prop.GetValue(o, null); if (value == null) { continue; } var list = value as IList; if (list != null) { //try first icollection for syncroot List <object> elements; lock (list.SyncRoot) { elements = new List <object>(list.Count); //no foreach. Even .Cast can lead to Collection was modified after the enumerator was instantiated. for (int i = 0; i < list.Count; i++) { var item = list[i]; elements.Add(item); } } ScanPropertiesList(result, elements, level + 1, visitedObjects); } else { var enumerable = value as IEnumerable; if (enumerable != null) { //cast to list otherwhise possible: Collection was modified after the enumerator was instantiated. var elements = enumerable as IList <object> ?? enumerable.Cast <object>().ToList(); ScanPropertiesList(result, elements, level + 1, visitedObjects); } else { ScanProperties(result, value, level + 1, visitedObjects); } } } }
/// <remarks>ISet is not there in .net35, so using HashSet</remarks> private static void ScanProperties <T>(bool aggressiveSearch, List <T> result, object o, int level, HashSet <object> visitedObjects) where T : class { if (o == null) { return; } var type = o.GetType(); try { if (type == null || !type.IsDefined(typeof(NLogConfigurationItemAttribute), true)) { return; } } catch (System.Exception ex) { InternalLogger.Info(ex, "{0}Type reflection not possible for: {1}. Maybe because of .NET Native.", new string(' ', level), o.ToString()); return; } if (visitedObjects.Contains(o)) { return; } visitedObjects.Add(o); if (InternalLogger.IsTraceEnabled) { InternalLogger.Trace("{0}Scanning {1} '{2}'", new string(' ', level), type.Name, o); } var t = o as T; if (t != null) { result.Add(t); if (!aggressiveSearch) { return; } } foreach (PropertyInfo prop in PropertyHelper.GetAllReadableProperties(type)) { if (prop == null || prop.PropertyType == null || prop.PropertyType.IsPrimitive() || prop.PropertyType.IsEnum() || prop.PropertyType == typeof(string)) { continue; } try { if (prop.IsDefined(typeof(NLogConfigurationIgnorePropertyAttribute), true)) { continue; } } catch (System.Exception ex) { InternalLogger.Info(ex, "{0}Type reflection not possible for property {1}. Maybe because of .NET Native.", new string(' ', level + 1), prop.Name); continue; } object value = prop.GetValue(o, null); if (value == null) { continue; } if (InternalLogger.IsTraceEnabled) { InternalLogger.Trace("{0}Scanning Property {1} '{2}' {3}", new string(' ', level + 1), prop.Name, value.ToString(), prop.PropertyType.Namespace); } var list = value as IList; if (list != null) { //try first icollection for syncroot List <object> elements; lock (list.SyncRoot) { elements = new List <object>(list.Count); //no foreach. Even .Cast can lead to Collection was modified after the enumerator was instantiated. for (int i = 0; i < list.Count; i++) { var item = list[i]; elements.Add(item); } } ScanPropertiesList(aggressiveSearch, result, elements, level + 1, visitedObjects); } else { var enumerable = value as IEnumerable; if (enumerable != null) { //new list to prevent: Collection was modified after the enumerator was instantiated. var elements = enumerable as IList <object> ?? enumerable.Cast <object>().ToList(); //note .Cast is tread-unsafe! But at least it isn't a ICollection / IList ScanPropertiesList(aggressiveSearch, result, elements, level + 1, visitedObjects); } else { #if NETSTANDARD if (!prop.PropertyType.IsDefined(typeof(NLogConfigurationItemAttribute), true)) { continue; // .NET native doesn't always allow reflection of System-types (Ex. Encoding) } #endif ScanProperties(aggressiveSearch, result, value, level + 1, visitedObjects); } } } }
private static void ScanProperties <T>(List <T> result, object o, int level, HashSet <object> visitedObjects) where T : class { if (o == null) { return; } //cheaper call then getType and isDefined if (visitedObjects.Contains(o)) { return; } var type = o.GetType(); if (!type.IsDefined(typeof(NLogConfigurationItemAttribute), true)) { return; } visitedObjects.Add(o); var t = o as T; if (t != null) { result.Add(t); } if (InternalLogger.IsTraceEnabled) { InternalLogger.Trace("{0}Scanning {1} '{2}'", new string(' ', level), type.Name, o); } var allReadableProperties = PropertyHelper.GetAllReadableProperties(type).ToList(); foreach (PropertyInfo prop in allReadableProperties) { if (prop.PropertyType.IsPrimitive || prop.PropertyType.IsEnum || prop.PropertyType == typeof(string) || prop.IsDefined(typeof(NLogConfigurationIgnorePropertyAttribute), true)) { continue; } object value = prop.GetValue(o, null); if (value == null) { continue; } var enumerable = value as IEnumerable; if (enumerable != null) { //new list to prevent: Collection was modified after the enumerator was instantiated. var elements = new List <object>(enumerable.Cast <object>()); foreach (object element in elements) { ScanProperties(result, element, level + 1, visitedObjects); } } else { ScanProperties(result, value, level + 1, visitedObjects); } } }