/// <summary> /// Initializes a new instance of the <see cref="ShellService" /> class. /// </summary> /// <param name="typeFactory">The type factory.</param> /// <param name="keyboardMappingsService">The keyboard mappings service.</param> /// <param name="commandManager">The command manager.</param> /// <param name="splashScreenService">The splash screen service.</param> /// <param name="applicationInitializationService">The application initialization service.</param> /// <param name="dependencyResolver">The dependency resolver.</param> /// <exception cref="ArgumentNullException">The <paramref name="typeFactory" /> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">The <paramref name="keyboardMappingsService" /> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">The <paramref name="commandManager" /> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">The <paramref name="splashScreenService" /> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">The <paramref name="applicationInitializationService" /> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">The <paramref name="dependencyResolver" /> is <c>null</c>.</exception> public CustomShellService(ITypeFactory typeFactory, IKeyboardMappingsService keyboardMappingsService, ICommandManager commandManager, ISplashScreenService splashScreenService, IApplicationInitializationService applicationInitializationService, IDependencyResolver dependencyResolver) { Argument.IsNotNull(() => typeFactory); Argument.IsNotNull(() => keyboardMappingsService); Argument.IsNotNull(() => commandManager); Argument.IsNotNull(() => splashScreenService); Argument.IsNotNull(() => applicationInitializationService); Argument.IsNotNull(() => dependencyResolver); _typeFactory = typeFactory; _keyboardMappingsService = keyboardMappingsService; _commandManager = commandManager; _splashScreenService = splashScreenService; _applicationInitializationService = applicationInitializationService; _dependencyResolver = dependencyResolver; var entryAssembly = AssemblyHelper.GetEntryAssembly(); Log.Info("Starting {0} v{1} ({2})", entryAssembly.Title(), entryAssembly.Version(), entryAssembly.InformationalVersion()); // Initialize (now we have an application) }
/// <summary> /// Initializes the types in the specified assembly. It does this by looping through all loaded assemblies and /// registering the type by type name and assembly name. /// <para/> /// The types initialized by this method are used by <see cref="object.GetType"/>. /// </summary> /// <param name="forceFullInitialization">If <c>true</c>, the types are initialized, even when the types are already initialized.</param> /// <param name="assembly">The assembly to initialize the types from. If <c>null</c>, all assemblies will be checked.</param> public static void InitializeTypes(bool forceFullInitialization, Assembly assembly = null) { bool checkSingleAssemblyOnly = assembly != null; if (!forceFullInitialization && !checkSingleAssemblyOnly && (_typesWithAssembly != null)) { return; } lock (_lockObject) { if (forceFullInitialization) { _typesWithAssembly.Clear(); _typesWithAssembly = null; _typesWithAssemblyLowerCase.Clear(); _typesWithAssemblyLowerCase = null; _typesWithoutAssembly.Clear(); _typesWithoutAssembly = null; _typesWithoutAssemblyLowerCase.Clear(); _typesWithoutAssemblyLowerCase = null; } if (_typesWithAssembly == null) { _typesWithAssembly = new Dictionary <string, Type>(); } if (_typesWithAssemblyLowerCase == null) { _typesWithAssemblyLowerCase = new Dictionary <string, Type>(); } if (_typesWithoutAssembly == null) { _typesWithoutAssembly = new Dictionary <string, string>(); } if (_typesWithoutAssemblyLowerCase == null) { _typesWithoutAssemblyLowerCase = new Dictionary <string, string>(); } var typesToAdd = new HashSet <Type>(); var assembliesToLoad = new List <Assembly>(); if (assembly != null) { assembliesToLoad.Add(assembly); } else { assembliesToLoad.AddRange(AssemblyHelper.GetLoadedAssemblies()); } foreach (var loadedAssembly in assembliesToLoad) { try { foreach (var type in AssemblyHelper.GetAllTypesSafely(loadedAssembly)) { typesToAdd.Add(type); } } catch (Exception ex) { Log.Warning(ex, "Failed to get all types in assembly '{0}'", loadedAssembly.FullName); } } foreach (var type in typesToAdd) { var newAssemblyName = TypeHelper.GetAssemblyNameWithoutOverhead(type.GetAssemblyFullNameEx()); string newFullType = TypeHelper.FormatType(newAssemblyName, type.FullName); if (!_typesWithAssembly.ContainsKey(newFullType)) { _typesWithAssembly[newFullType] = type; _typesWithAssemblyLowerCase[newFullType.ToLowerInvariant()] = type; var typeNameWithoutAssembly = TypeHelper.GetTypeName(newFullType); _typesWithoutAssembly[typeNameWithoutAssembly] = newFullType; _typesWithoutAssemblyLowerCase[typeNameWithoutAssembly.ToLowerInvariant()] = newFullType; } } } }
/// <summary> /// Gets the build date time of the assembly. /// </summary> /// <param name="assembly">The assembly.</param> /// <returns>DateTime.</returns> public static DateTime GetBuildDateTime(this Assembly assembly) { Argument.IsNotNull("assembly", assembly); return(AssemblyHelper.GetLinkerTimestamp(assembly.Location)); }
/// <summary> /// Gets the type. /// </summary> /// <param name="typeName">Name of the type.</param> /// <param name="assemblyName">Name of the assembly. Can be <c>null</c> if no assembly is known.</param> /// <param name="ignoreCase">A value indicating whether the case should be ignored.</param> /// <returns>The <see cref="Type"/> or <c>null</c> if the type cannot be found.</returns> /// <exception cref="ArgumentException">The <paramref name="typeName"/> is <c>null</c> or whitespace.</exception> private static Type GetType(string typeName, string assemblyName, bool ignoreCase) { Argument.IsNotNullOrWhitespace("typeName", typeName); InitializeTypes(false); lock (_lockObject) { var typesWithoutAssembly = ignoreCase ? _typesWithoutAssemblyLowerCase : _typesWithoutAssembly; var typesWithAssembly = ignoreCase ? _typesWithAssemblyLowerCase : _typesWithAssembly; if (ignoreCase) { typeName = typeName.ToLowerInvariant(); } var typeNameWithAssembly = string.IsNullOrEmpty(assemblyName) ? null : TypeHelper.FormatType(assemblyName, typeName); if (typeNameWithAssembly == null) { // Simple types without assembly cannot be resolved afterwards, thus if it is not known // at this point, just return null; // // This *must* be the case-sensitive dictionary because a case-correct one will be resolved from // typesWithoutAssembly[typeName] return(typesWithoutAssembly.ContainsKey(typeName) ? _typesWithAssembly[typesWithoutAssembly[typeName]] : null); } if (typesWithAssembly.ContainsKey(typeNameWithAssembly)) { return(typesWithAssembly[typeNameWithAssembly]); } // Try to remove version info from assembly info var assemblyNameWithoutOverhead = TypeHelper.GetAssemblyNameWithoutOverhead(assemblyName); var typeNameWithoutAssemblyOverhead = TypeHelper.FormatType(assemblyNameWithoutOverhead, typeName); if (typesWithAssembly.ContainsKey(typeNameWithoutAssemblyOverhead)) { return(typesWithAssembly[typeNameWithoutAssemblyOverhead]); } // Fallback to GetType try { #if NETFX_CORE var type = Type.GetType(typeNameWithAssembly, false); #elif SILVERLIGHT // Due to a FileLoadException when loading types without a specific version, we need to map the assembly version here var assemblyNameWithVersion = AssemblyHelper.GetAssemblyNameWithVersion(assemblyName); var typeNameWithAssemblyNameWithVersion = TypeHelper.FormatType(assemblyNameWithVersion, typeName); var type = Type.GetType(typeNameWithAssemblyNameWithVersion, false, ignoreCase); #else var type = Type.GetType(typeNameWithAssembly, false, ignoreCase); #endif if (type != null) { typesWithAssembly.Add(typeNameWithAssembly, type); return(type); } } #if !NETFX_CORE catch (System.IO.FileLoadException fle) { Log.Debug(fle, "Failed to load type '{0}' using Type.GetType(), failed to load file", typeNameWithAssembly); } #endif catch (Exception ex) { Log.Debug(ex, "Failed to load type '{0}' using Type.GetType()", typeNameWithAssembly); } // Fallback for this assembly only InitializeTypes(false, assemblyName); if (typesWithAssembly.ContainsKey(typeNameWithAssembly)) { return(typesWithAssembly[typeNameWithAssembly]); } if (typesWithAssembly.ContainsKey(typeNameWithoutAssemblyOverhead)) { return(typesWithAssembly[typeNameWithoutAssemblyOverhead]); } } return(null); }
/// <summary> /// Initializes the types in the specified assembly. It does this by looping through all loaded assemblies and /// registering the type by type name and assembly name. /// <para/> /// The types initialized by this method are used by <see cref="object.GetType"/>. /// </summary> /// <param name="assembly">The assembly to initialize the types from. If <c>null</c>, all assemblies will be checked.</param> /// <param name="forceFullInitialization">If <c>true</c>, the types are initialized, even when the types are already initialized.</param> /// <param name="allowMultithreadedInitialization">If <c>true</c>, allow multithreaded initialization. The default value is <c>false</c>.</param> public static void InitializeTypes(Assembly assembly = null, bool forceFullInitialization = false, bool allowMultithreadedInitialization = false) { // Important note: only allow explicit multithreaded initialization var checkSingleAssemblyOnly = assembly != null; lock (_lockObject) { if (_hasInitializedOnce && !forceFullInitialization && !checkSingleAssemblyOnly) { return; } if (!checkSingleAssemblyOnly) { _hasInitializedOnce = true; } // CTL-877 Only clear when assembly != null if (forceFullInitialization && assembly is null) { _loadedAssemblies.Clear(); _typesByAssembly?.Clear(); _typesWithAssembly?.Clear(); _typesWithAssemblyLowerCase?.Clear(); _typesWithoutAssembly?.Clear(); _typesWithoutAssemblyLowerCase?.Clear(); } var assembliesToInitialize = checkSingleAssemblyOnly ? new List <Assembly>(new[] { assembly }) : AssemblyHelper.GetLoadedAssemblies(); InitializeAssemblies(assembliesToInitialize, forceFullInitialization, allowMultithreadedInitialization); } }
private static void InitializeAssemblies(IEnumerable <Assembly> assemblies) { lock (_lockObject) { var typesToAdd = new Dictionary <Assembly, HashSet <Type> >(); foreach (var assembly in assemblies) { var loadedAssemblyFullName = assembly.FullName; try { if (_loadedAssemblies.Contains(loadedAssemblyFullName)) { continue; } _loadedAssemblies.Add(loadedAssemblyFullName); if (ShouldIgnoreAssembly(assembly)) { continue; } typesToAdd[assembly] = new HashSet <Type>(); foreach (var type in AssemblyHelper.GetAllTypesSafely(assembly)) { typesToAdd[assembly].Add(type); } } catch (Exception ex) { Log.Warning(ex, "Failed to get all types in assembly '{0}'", loadedAssemblyFullName); } } foreach (var assemblyWithTypes in typesToAdd) { foreach (var type in assemblyWithTypes.Value) { InitializeType(assemblyWithTypes.Key, type); } } #if NET var lateLoadedAssemblies = new List <Assembly>(); lock (_threadSafeAssemblyQueue) { while (_threadSafeAssemblyQueue.Count > 0) { var assembly = _threadSafeAssemblyQueue.Dequeue(); lateLoadedAssemblies.Add(assembly); } } if (lateLoadedAssemblies.Count > 0) { InitializeAssemblies(lateLoadedAssemblies); } #endif } }
/// <summary> /// Initializes the types in the specified assembly. It does this by looping through all loaded assemblies and /// registering the type by type name and assembly name. /// <para/> /// The types initialized by this method are used by <see cref="object.GetType"/>. /// </summary> /// <param name="assembly">The assembly to initialize the types from. If <c>null</c>, all assemblies will be checked.</param> /// <param name="forceFullInitialization">If <c>true</c>, the types are initialized, even when the types are already initialized.</param> public static void InitializeTypes(Assembly assembly = null, bool forceFullInitialization = false) { bool checkSingleAssemblyOnly = assembly != null; if (!forceFullInitialization && !checkSingleAssemblyOnly && (_typesWithAssembly != null)) { return; } lock (_lockObject) { if (forceFullInitialization) { _loadedAssemblies.Clear(); if (_typesByAssembly != null) { _typesByAssembly.Clear(); _typesByAssembly = null; } if (_typesWithAssembly != null) { _typesWithAssembly.Clear(); _typesWithAssembly = null; } if (_typesWithAssemblyLowerCase != null) { _typesWithAssemblyLowerCase.Clear(); _typesWithAssemblyLowerCase = null; } if (_typesWithoutAssembly != null) { _typesWithoutAssembly.Clear(); _typesWithoutAssembly = null; } if (_typesWithoutAssemblyLowerCase != null) { _typesWithoutAssemblyLowerCase.Clear(); _typesWithoutAssemblyLowerCase = null; } } if (_typesByAssembly == null) { _typesByAssembly = new Dictionary <string, Dictionary <string, Type> >(); } if (_typesWithAssembly == null) { _typesWithAssembly = new Dictionary <string, Type>(); } if (_typesWithAssemblyLowerCase == null) { _typesWithAssemblyLowerCase = new Dictionary <string, Type>(); } if (_typesWithoutAssembly == null) { _typesWithoutAssembly = new Dictionary <string, string>(); } if (_typesWithoutAssemblyLowerCase == null) { _typesWithoutAssemblyLowerCase = new Dictionary <string, string>(); } var assembliesToInitialize = checkSingleAssemblyOnly ? new List <Assembly>(new[] { assembly }) : AssemblyHelper.GetLoadedAssemblies(); InitializeAssemblies(assembliesToInitialize); } }
/// <summary> /// Gets the type. /// </summary> /// <param name="typeName">Name of the type.</param> /// <param name="assemblyName">Name of the assembly. Can be <c>null</c> if no assembly is known.</param> /// <param name="ignoreCase">A value indicating whether the case should be ignored.</param> /// <returns>The <see cref="Type"/> or <c>null</c> if the type cannot be found.</returns> /// <exception cref="ArgumentException">The <paramref name="typeName"/> is <c>null</c> or whitespace.</exception> private static Type GetType(string typeName, string assemblyName, bool ignoreCase) { Argument.IsNotNullOrWhitespace("typeName", typeName); InitializeTypes(); lock (_lockObject) { var typesWithoutAssembly = ignoreCase ? _typesWithoutAssemblyLowerCase : _typesWithoutAssembly; var typesWithAssembly = ignoreCase ? _typesWithAssemblyLowerCase : _typesWithAssembly; if (ignoreCase) { typeName = typeName.ToLowerInvariant(); } var typeNameWithAssembly = string.IsNullOrEmpty(assemblyName) ? null : TypeHelper.FormatType(assemblyName, typeName); if (typeNameWithAssembly == null) { if (typesWithoutAssembly.ContainsKey(typeName)) { return(typesWithAssembly[typesWithoutAssembly[typeName]]); } // Note that lazy-loaded types (a few lines below) are added to the types *with* assemblies so we have // a direct access cache if (typesWithAssembly.ContainsKey(typeName)) { return(typesWithAssembly[typeName]); } var fallbackType = GetTypeBySplittingInternals(typeName); if (fallbackType != null) { // Though it was not initially found, we still have found a new type, register it typesWithAssembly[typeName] = fallbackType; } return(fallbackType); } if (typesWithAssembly.ContainsKey(typeNameWithAssembly)) { return(typesWithAssembly[typeNameWithAssembly]); } // Try to remove version info from assembly info var assemblyNameWithoutOverhead = TypeHelper.GetAssemblyNameWithoutOverhead(assemblyName); var typeNameWithoutAssemblyOverhead = TypeHelper.FormatType(assemblyNameWithoutOverhead, typeName); if (typesWithAssembly.ContainsKey(typeNameWithoutAssemblyOverhead)) { return(typesWithAssembly[typeNameWithoutAssemblyOverhead]); } // Fallback to GetType try { #if NETFX_CORE || PCL var type = Type.GetType(typeNameWithAssembly, false); #elif SILVERLIGHT // Due to a FileLoadException when loading types without a specific version, we need to map the assembly version here var assemblyNameWithVersion = AssemblyHelper.GetAssemblyNameWithVersion(assemblyName); var typeNameWithAssemblyNameWithVersion = TypeHelper.FormatType(assemblyNameWithVersion, typeName); var type = Type.GetType(typeNameWithAssemblyNameWithVersion, false, ignoreCase); #else var type = Type.GetType(typeNameWithAssembly, false, ignoreCase); #endif if (type != null) { typesWithAssembly.Add(typeNameWithAssembly, type); return(type); } } #if !NETFX_CORE && !PCL catch (System.IO.FileLoadException fle) { Log.Debug(fle, "Failed to load type '{0}' using Type.GetType(), failed to load file", typeNameWithAssembly); } #endif catch (Exception ex) { Log.Debug(ex, "Failed to load type '{0}' using Type.GetType()", typeNameWithAssembly); } // Fallback for this assembly only InitializeTypes(false, assemblyName); if (typesWithAssembly.ContainsKey(typeNameWithAssembly)) { return(typesWithAssembly[typeNameWithAssembly]); } if (typesWithAssembly.ContainsKey(typeNameWithoutAssemblyOverhead)) { return(typesWithAssembly[typeNameWithoutAssemblyOverhead]); } } return(null); }