/// <summary> /// Load from url /// </summary> /// <param name="assemblyName">name without .dll</param> /// <returns></returns> public static Assembly LoadFromName(string assemblyName) { InternalLogger.Info("Loading assembly: {0}", assemblyName); #if NETSTANDARD1_0 || WINDOWS_PHONE var name = new AssemblyName(assemblyName); return(Assembly.Load(name)); #elif SILVERLIGHT && !WINDOWS_PHONE //as embedded resource var assemblyFile = assemblyName + ".dll"; var stream = Application.GetResourceStream(new Uri(assemblyFile, UriKind.Relative)); var assemblyPart = new AssemblyPart(); Assembly assembly = assemblyPart.Load(stream.Stream); return(assembly); #else try { Assembly assembly = Assembly.Load(assemblyName); return(assembly); } catch (FileNotFoundException) { var name = new AssemblyName(assemblyName); InternalLogger.Trace("Try find '{0}' in current domain", assemblyName); var loadedAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(domainAssembly => IsAssemblyMatch(name, domainAssembly.GetName())); if (loadedAssembly != null) { InternalLogger.Trace("Found '{0}' in current domain", assemblyName); return(loadedAssembly); } InternalLogger.Trace("Haven't found' '{0}' in current domain", assemblyName); throw; } #endif }
/// <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); } } }