/// <summary> /// Determine if a given type name is in the assembly or not. Return null if the type is not in the assembly /// </summary> internal LoadedType GetLoadedTypeByTypeName(string typeName) { ErrorUtilities.VerifyThrowArgumentNull(typeName, "typeName"); // Only one thread should be doing operations on this instance of the object at a time. Type type = _typeNameToType.GetOrAdd(typeName, (key) => { if ((_assemblyLoadInfo.AssemblyName != null) && (typeName.Length > 0)) { try { // try to load the type using its assembly qualified name Type t2 = Type.GetType(typeName + "," + _assemblyLoadInfo.AssemblyName, false /* don't throw on error */, true /* case-insensitive */); if (t2 != null) { return(!_isDesiredType(t2, null) ? null : t2); } } 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 (Interlocked.Read(ref _haveScannedPublicTypes) == 0) { lock (_lockObject) { if (Interlocked.Read(ref _haveScannedPublicTypes) == 0) { ScanAssemblyForPublicTypes(); Interlocked.Exchange(ref _haveScannedPublicTypes, ~0); } } } foreach (KeyValuePair <string, Type> desiredTypeInAssembly in _publicTypeNameToType) { // if type matches partially on its name if (typeName.Length == 0 || TypeLoader.IsPartialTypeNameMatch(desiredTypeInAssembly.Key, typeName)) { return(desiredTypeInAssembly.Value); } } return(null); }); return(type != null ? new LoadedType(type, _assemblyLoadInfo, _loadedAssembly) : null); }
/// <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> private LoadedType GetLoadedType(Concurrent.ConcurrentDictionary <TypeFilter, Concurrent.ConcurrentDictionary <AssemblyLoadInfo, AssemblyInfoToLoadedTypes> > cache, string typeName, AssemblyLoadInfo assembly) { // A given type filter have been used on a number of assemblies, Based on the type filter we will get another dictionary which // will map a specific AssemblyLoadInfo to a AssemblyInfoToLoadedTypes class which knows how to find a typeName in a given assembly. Concurrent.ConcurrentDictionary <AssemblyLoadInfo, AssemblyInfoToLoadedTypes> loadInfoToType = cache.GetOrAdd(_isDesiredType, (_) => new Concurrent.ConcurrentDictionary <AssemblyLoadInfo, AssemblyInfoToLoadedTypes>()); // Get an object which is able to take a typename and determine if it is in the assembly pointed to by the AssemblyInfo. AssemblyInfoToLoadedTypes typeNameToType = loadInfoToType.GetOrAdd(assembly, (_) => new AssemblyInfoToLoadedTypes(_isDesiredType, _)); return(typeNameToType.GetLoadedTypeByTypeName(typeName)); }