/// <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) { 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 = Type.GetType(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); }
/// <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); }