| File: System\Configuration\TypeUtil.cs | Web Access |
| Project: src\runtime\src\libraries\System.Configuration.ConfigurationManager\src\System.Configuration.ConfigurationManager.csproj (System.Configuration.ConfigurationManager) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Configuration.Internal; using System.Reflection; namespace System.Configuration { internal static class TypeUtil { internal const string ConfigurationManagerAssemblyName = "System.Configuration.ConfigurationManager"; // Deliberately not being explicit about the versions to make // things simpler for consumers of System.Configuration. private static readonly string[] s_implicitAssemblies = { // Historically we would find types in System.dll here. // This is because Configuration used to live in System.dll // and by resolution rules, typenames without an assembly // specifier would be found there: // // (current executing assembly -> mscorlib / now s.p.c.l) // // When Configuration types moved to System.Configuration // the implicit lookup for System had to be added to keep // existing configuration files working. // We also need to find types in mscorlib.dll as currently // only types found in System.Private.CoreLib.dll are // implicitly resolved. If this changes we can remove the // explicit mscorlib lookup. "mscorlib", "System", }; /// <summary> /// Find type references that used to be found without assembly names /// </summary> private static Type GetImplicitType(string typeString) { // Since the config APIs were originally implemented in System.dll, // references to types without assembly names could be resolved if // they lived in System.dll. // // On .NET Framework we would try to emulate that behavior by looking in // System. As types have moved around in .NET Core, we'll try to load // from the a variety of assemblies to mimick the old behavior. // Don't bother to look around if we've already got something that // is clearly not a simple type name. if (string.IsNullOrEmpty(typeString) || typeString.Contains(',')) return null; // Ignore all exceptions, otherwise callers will get unexpected // exceptions not related to the original failure to load the // desired type. // First attempt is against our own System.Configuration types try { Assembly configurationAssembly = typeof(ConfigurationException).Assembly; Type type = configurationAssembly.GetType(typeString, false); if (type != null) return type; } catch { } foreach (string assembly in s_implicitAssemblies) { try { Type type = Type.GetType($"{typeString}, {assembly}"); if (type != null) return type; } catch { } } return null; } // Get the type specified by typeString. If it fails, try to retrieve it // as a type from System.dll. If that fails, return null or throw the original // exception as indicated by throwOnError. internal static Type GetType(string typeString, bool throwOnError) { Type type; try { type = Type.GetType(typeString, throwOnError); } catch { type = GetImplicitType(typeString); if (type == null) { throw; } } return type ?? GetImplicitType(typeString); } // Ask the host to get the type specified by typeString. If it fails, try to retrieve it // as a type from System.dll. If that fails, return null or throw the original // exception as indicated by throwOnError. internal static Type GetType(IInternalConfigHost host, string typeString, bool throwOnError) { Type type; try { type = host.GetConfigType(typeString, throwOnError); } catch { type = GetImplicitType(typeString); if (type == null) { throw; } } return type ?? GetImplicitType(typeString); } internal static T CreateInstance<T>(string typeString) { Type type = GetType(typeString, true); VerifyAssignableType(typeof(T), type, true); return (T)Activator.CreateInstance(type, true); } internal static object CreateInstance(Type type) { return Activator.CreateInstance(type, true); } internal static ConstructorInfo GetConstructor(Type type, Type baseType, bool throwOnError) { type = VerifyAssignableType(baseType, type, throwOnError); if (type == null) return null; const BindingFlags BindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; ConstructorInfo ctor = type.GetConstructor(BindingFlags, null, CallingConventions.HasThis, Type.EmptyTypes, null); if ((ctor == null) && throwOnError) throw new TypeLoadException(SR.Format(SR.TypeNotPublic, type.AssemblyQualifiedName)); return ctor; } internal static Type VerifyAssignableType(Type baseType, Type type, bool throwOnError) { if (baseType.IsAssignableFrom(type)) return type; if (throwOnError) { throw new TypeLoadException( SR.Format(SR.Config_type_doesnt_inherit_from_type, type.FullName, baseType.FullName)); } return null; } } }