/// <summary> /// Creates an instance of this class for the given type. /// </summary> /// <owner>SumedhK</owner> /// <param name="type"></param> /// <param name="assembly"></param> internal LoadedType(Type type, AssemblyLoadInfo assembly) { ErrorUtilities.VerifyThrow(type != null, "We must have the type."); ErrorUtilities.VerifyThrow(assembly != null, "We must have the assembly the type was loaded from."); this.type = type; this.assembly = assembly; }
/// <summary> /// Determines if two AssemblyLoadInfos are effectively the same. /// </summary> /// <returns></returns> /// <owner>RGoel</owner> public override bool Equals(Object obj) { if (obj == null) { return(false); } AssemblyLoadInfo otherAssemblyInfo = obj as AssemblyLoadInfo; if (otherAssemblyInfo == null) { return(false); } return((this.AssemblyName == otherAssemblyInfo.AssemblyName) && (this.AssemblyFile == otherAssemblyInfo.AssemblyFile)); }
/// <summary> /// Loads the specified type if it exists in the given assembly. If the type name is fully qualified, then a match (if /// any) is unambiguous; otherwise, if there are multiple types with the same name in different namespaces, the first type /// found will be returned. /// </summary> /// <remarks>This method throws exceptions -- it is the responsibility of the caller to handle them.</remarks> /// <owner>SumedhK</owner> /// <param name="typeName">Can be empty string.</param> /// <param name="assembly"></param> /// <returns>The loaded type, or null if the type was not found.</returns> internal LoadedType Load ( string typeName, AssemblyLoadInfo assembly ) { Type type = null; // Maybe we've already cracked open this assembly before. If so, just grab the list // of public desired types that we found last time. List <Type> desiredTypesInAssembly = null; cacheOfAllDesiredTypesInAnAssembly.TryGetValue(assembly, out desiredTypesInAssembly); // If we have the assembly name (strong or weak), and we haven't cracked this assembly open // before to discover all the public desired types. if ((assembly.AssemblyName != null) && (typeName.Length > 0) && (desiredTypesInAssembly == null)) { try { // try to load the type using its assembly qualified name type = Type.GetType(typeName + "," + assembly.AssemblyName, false /* don't throw on error */, true /* case-insensitive */); } catch (ArgumentException) { // Type.GetType() will throw this exception if the type name is invalid -- but we have no idea if it's the // type or the assembly name that's the problem -- so just ignore the exception, because we're going to // check the existence/validity of the assembly and type respectively, below anyway } } // if we found the type, it means its assembly qualified name was also its fully qualified name if (type != null) { // if it's not the right type, bail out -- there's no point searching further since we already matched on the // fully qualified name if (!isDesiredType(type, null)) { return(null); } } // if the type name was not fully qualified, or if we only have the assembly file/path else { if (desiredTypesInAssembly == null) { // we need to search the assembly for the type... Assembly loadedAssembly; try { if (assembly.AssemblyName != null) { loadedAssembly = Assembly.Load(assembly.AssemblyName); } else { loadedAssembly = Assembly.UnsafeLoadFrom(assembly.AssemblyFile); } } // Assembly.Load() and Assembly.LoadFrom() will throw an ArgumentException if the assembly name is invalid catch (ArgumentException e) { // convert to a FileNotFoundException because it's more meaningful // NOTE: don't use ErrorUtilities.VerifyThrowFileExists() here because that will hit the disk again throw new FileNotFoundException(null, assembly.ToString(), e); } // only look at public types Type[] allPublicTypesInAssembly = loadedAssembly.GetExportedTypes(); desiredTypesInAssembly = new List <Type>(); foreach (Type publicType in allPublicTypesInAssembly) { if (isDesiredType(publicType, null)) { desiredTypesInAssembly.Add(publicType); } } // Save the list of desired types into our cache, so that we don't have to crack it // open again. cacheOfAllDesiredTypesInAnAssembly[assembly] = desiredTypesInAssembly; } foreach (Type desiredTypeInAssembly in desiredTypesInAssembly) { // if type matches partially on its name if ((typeName.Length == 0) || IsPartialTypeNameMatch(desiredTypeInAssembly.FullName, typeName)) { type = desiredTypeInAssembly; break; } } } if (type != null) { return(new LoadedType(type, assembly)); } return(null); }