/// <summary>根据名称获取类型</summary> /// <param name="typeName">类型名</param> /// <param name="isLoadAssembly">是否从未加载程序集中获取类型。使用仅反射的方法检查目标类型,如果存在,则进行常规加载</param> /// <returns></returns> public virtual Type GetType(String typeName, Boolean isLoadAssembly) { //var type = Type.GetType(typeName); //if (type != null) return type; return(AssemblyX.GetType(typeName, isLoadAssembly)); }
/// <summary>根据名称获取类型</summary> /// <param name="typeName">类型名</param> /// <param name="isLoadAssembly">是否从未加载程序集中获取类型。使用仅反射的方法检查目标类型,如果存在,则进行常规加载</param> /// <returns></returns> public virtual Type GetType(String typeName, Boolean isLoadAssembly) { #if !__CORE__ return(AssemblyX.GetType(typeName, isLoadAssembly)); #else return(Type.GetType(typeName)); #endif }
/// <summary>在所有程序集中查找指定基类或接口的子类实现</summary> /// <param name="baseType">基类或接口</param> /// <param name="isLoadAssembly">是否加载为加载程序集</param> /// <returns></returns> public virtual IEnumerable <Type> GetAllSubclasses(Type baseType, Boolean isLoadAssembly) { //// 不支持isLoadAssembly //foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) //{ // foreach (var type in GetSubclasses(asm, baseType)) // { // yield return type; // } //} return(AssemblyX.FindAllPlugins(baseType, isLoadAssembly)); }
/// <summary>在指定程序集中查找指定基类的子类</summary> /// <param name="asm">指定程序集</param> /// <param name="baseType">基类或接口,为空时返回所有类型</param> /// <returns></returns> public virtual IEnumerable <Type> GetSubclasses(Assembly asm, Type baseType) { //if (asm == null) throw new ArgumentNullException(nameof(asm)); //if (baseType == null) throw new ArgumentNullException(nameof(baseType)); //foreach (var item in asm.GetTypes()) //{ // if (baseType != item && baseType.IsAssignableFrom(item)) // yield return item; //} return(AssemblyX.Create(asm).FindPlugins(baseType)); }
/// <summary>只反射加载指定路径的所有程序集</summary> /// <param name="path"></param> /// <returns></returns> public static IEnumerable <AssemblyX> ReflectionOnlyLoad(String path) { if (!Directory.Exists(path)) { yield break; } // 先返回已加载的只加载程序集 var loadeds2 = AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies().Select(e => Create(e)).ToList(); // 再去遍历目录 var ss = Directory.GetFiles(path, "*.*", SearchOption.TopDirectoryOnly); if (ss == null || ss.Length < 1) { yield break; } var loadeds = AssemblyX.GetAssemblies().ToList(); foreach (var item in ss) { if (!item.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) && !item.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) { continue; } if (loadeds.Any(e => e.Location.EqualIgnoreCase(item)) || loadeds2.Any(e => e.Location.EqualIgnoreCase(item))) { continue; } AssemblyX asmx = null; try { //Assembly asm = Assembly.ReflectionOnlyLoad(File.ReadAllBytes(item)); var asm = Assembly.ReflectionOnlyLoadFrom(item); asmx = Create(asm); } catch { } if (asmx != null) { yield return(asmx); } } }
private static Type GetTypeInternal(String typeName, Boolean isLoadAssembly) { if (String.IsNullOrEmpty(typeName)) { throw new ArgumentNullException("typeName"); } // 基本获取 Type type = Type.GetType(typeName); if (type != null) { return(type); } #region 处理泛型 Int32 start = typeName.IndexOf("<"); if (start > 0) { Int32 end = typeName.LastIndexOf(">"); // <>也不行 if (end > start + 1) { // GT<P1,P2,P3,P4> String gname = typeName.Substring(0, start); String pname = typeName.Substring(start + 1, end - start - 1); //pname = "P1,P2<aa,bb>,P3,P4"; List <String> pnames = new List <String>(); // 只能用栈来分析泛型参数了 Int32 count = 0; Int32 last = 0; for (Int32 i = 0; i < pname.Length; i++) { Char item = pname[i]; if (item == '<') { count++; } else if (item == '>') { count--; } else if (item == ',' && count == 0) { pnames.Add(pname.Substring(last, i - last).Trim()); last = i + 1; } } if (last <= pname.Length) { pnames.Add(pname.Substring(last, pname.Length - last).Trim()); } gname += "`" + pnames.Count; // 先找外部的,如果外部都找不到,那就没意义了 Type gt = GetType(gname, isLoadAssembly); if (gt == null) { return(null); } List <Type> ts = new List <Type>(pnames.Count); foreach (String item in pnames) { // 如果任何一个参数为空,说明这只是一个泛型定义而已 if (String.IsNullOrEmpty(item)) { return(gt); } Type t = GetType(item, isLoadAssembly); if (t == null) { return(null); } ts.Add(t); } return(gt.MakeGenericType(ts.ToArray())); } } #endregion #region 处理数组 start = typeName.LastIndexOf("["); if (start > 0) { Int32 end = typeName.LastIndexOf("]"); if (end > start) { // Int32[][] String[,,] String gname = typeName.Substring(0, start); String pname = typeName.Substring(start + 1, end - start - 1); // 先找外部的,如果外部都找不到,那就没意义了 Type gt = GetType(gname, isLoadAssembly); if (gt == null) { return(null); } if (String.IsNullOrEmpty(pname)) { return(gt.MakeArrayType()); } //pname = ",,,"; String[] pnames = pname.Split(new Char[] { ',' }); if (pnames == null || pnames.Length < 1) { return(gt.MakeArrayType()); } return(gt.MakeArrayType(pnames.Length)); } } #endregion // 处理内嵌类型 // 尝试本程序集 Assembly[] asms = new[] { Assembly.GetExecutingAssembly(), Assembly.GetCallingAssembly(), Assembly.GetEntryAssembly() }; var loads = new List <Assembly>(); foreach (var asm in asms) { if (asm == null || loads.Contains(asm)) { continue; } loads.Add(asm); type = asm.GetType(typeName); if (type != null) { return(type); } } // 尝试所有程序集 foreach (var asm in AssemblyX.GetAssemblies()) { if (loads.Contains(asm.Asm)) { continue; } loads.Add(asm.Asm); type = asm.GetType(typeName); if (type != null) { return(type); } } if (isLoadAssembly) { foreach (var asm in AssemblyX.ReflectionOnlyGetAssemblies()) { type = asm.GetType(typeName); if (type != null) { // 真实加载 var asm2 = Assembly.LoadFile(asm.Asm.Location); var type2 = AssemblyX.Create(asm2).GetType(typeName); if (type2 != null) { type = type2; } return(type); } } } //// 尝试系统的 //if (!typeName.Contains(".")) //{ // type = Type.GetType("System." + typeName); // if (type != null) return type; // type = Type.GetType("NewLife." + typeName); // if (type != null) return type; //} return(null); }
/// <summary>根据名称获取类型</summary> /// <param name="typeName">类型名</param> /// <param name="isLoadAssembly">是否从未加载程序集中获取类型。使用仅反射的方法检查目标类型,如果存在,则进行常规加载</param> /// <returns></returns> public virtual Type GetType(String typeName, Boolean isLoadAssembly) => AssemblyX.GetType(typeName, isLoadAssembly);
/// <summary>根据名称获取类型</summary> /// <param name="typeName">类型名</param> /// <param name="isLoadAssembly">是否从未加载程序集中获取类型。使用仅反射的方法检查目标类型,如果存在,则进行常规加载</param> /// <returns></returns> internal static Type GetType(String typeName, Boolean isLoadAssembly) { var type = Type.GetType(typeName); if (type != null) { return(type); } // 尝试本程序集 var asms = new[] { AssemblyX.Create(Assembly.GetExecutingAssembly()), AssemblyX.Create(Assembly.GetCallingAssembly()), AssemblyX.Create(Assembly.GetEntryAssembly()) }; var loads = new List <AssemblyX>(); foreach (var asm in asms) { if (asm == null || loads.Contains(asm)) { continue; } loads.Add(asm); type = asm.GetType(typeName); if (type != null) { return(type); } } // 尝试所有程序集 foreach (var asm in AssemblyX.GetAssemblies()) { if (loads.Contains(asm)) { continue; } loads.Add(asm); type = asm.GetType(typeName); if (type != null) { return(type); } } // 尝试加载只读程序集 if (!isLoadAssembly) { return(null); } foreach (var asm in ReflectionOnlyGetAssemblies()) { type = asm.GetType(typeName); if (type != null) { // 真实加载 var file = asm.Asm.Location; try { type = null; var asm2 = Assembly.LoadFile(file); var type2 = AssemblyX.Create(asm2).GetType(typeName); if (type2 == null) { continue; } type = type2; if (XTrace.Debug) { var root = ".".GetFullPath(); if (file.StartsWithIgnoreCase(root)) { file = file.Substring(root.Length).TrimStart("\\"); } XTrace.WriteLine("TypeX.GetType(\"{0}\") => {1}", typeName, file); } } catch (Exception ex) { if (XTrace.Debug) { XTrace.WriteException(ex); } } return(type); } } return(null); }
/// <summary>查找所有非系统程序集中的所有插件</summary> /// <remarks>继承类所在的程序集会引用baseType所在的程序集,利用这一点可以做一定程度的性能优化。</remarks> /// <param name="baseType"></param> /// <param name="isLoadAssembly">是否从未加载程序集中获取类型。使用仅反射的方法检查目标类型,如果存在,则进行常规加载</param> /// <param name="excludeGlobalTypes">指示是否应检查来自所有引用程序集的类型。如果为 false,则检查来自所有引用程序集的类型。 否则,只检查来自非全局程序集缓存 (GAC) 引用的程序集的类型。</param> /// <returns></returns> internal static IEnumerable <Type> FindAllPlugins(Type baseType, Boolean isLoadAssembly, Boolean excludeGlobalTypes) { var baseAssemblyName = baseType.Assembly.GetName().Name; var list = new List <Type>(); foreach (var item in GetAssemblies()) { // 如果excludeGlobalTypes为true,则指检查来自非GAC引用的程序集 if (excludeGlobalTypes && item.Asm.GlobalAssemblyCache) { continue; } // 不搜索系统程序集,不搜索未引用基类所在程序集的程序集,优化性能 if (item.IsSystemAssembly || !IsReferencedFrom(item.Asm, baseAssemblyName)) { continue; } var ts = item.FindPlugins(baseType); if (ts != null && ts.Count > 0) { foreach (var elm in ts) { if (!list.Contains(elm)) { list.Add(elm); yield return(elm); } } } } if (isLoadAssembly) { foreach (var item in AssemblyX.ReflectionOnlyGetAssemblies()) { // 如果excludeGlobalTypes为true,则指检查来自非GAC引用的程序集 if (excludeGlobalTypes && item.Asm.GlobalAssemblyCache) { continue; } // 不搜索系统程序集,不搜索未引用基类所在程序集的程序集,优化性能 if (item.IsSystemAssembly || !IsReferencedFrom(item.Asm, baseAssemblyName)) { continue; } var ts = item.FindPlugins(baseType); if (ts != null && ts.Count > 0) { // 真实加载 var asm2 = Assembly.LoadFile(item.Asm.Location); ts = AssemblyX.Create(asm2).FindPlugins(baseType); if (ts != null && ts.Count > 0) { foreach (var elm in ts) { if (!list.Contains(elm)) { list.Add(elm); yield return(elm); } } } } } } }
/// <summary>在所有程序集中查找指定基类或接口的子类实现</summary> /// <param name="baseType">基类或接口</param> /// <param name="isLoadAssembly">是否加载为加载程序集</param> /// <returns></returns> public override IEnumerable <Type> GetAllSubclasses(Type baseType, Boolean isLoadAssembly) { return(AssemblyX.FindAllPlugins(baseType, isLoadAssembly)); }
/// <summary>在指定程序集中查找指定基类的子类</summary> /// <param name="asm">指定程序集</param> /// <param name="baseType">基类或接口,为空时返回所有类型</param> /// <returns></returns> public override IEnumerable <Type> GetSubclasses(Assembly asm, Type baseType) { return(AssemblyX.Create(asm).FindPlugins(baseType)); }
/// <summary>根据名称获取类型</summary> /// <param name="typeName">类型名</param> /// <param name="isLoadAssembly">是否从未加载程序集中获取类型。使用仅反射的方法检查目标类型,如果存在,则进行常规加载</param> /// <returns></returns> public virtual Type GetType(String typeName, Boolean isLoadAssembly) { return(AssemblyX.GetType(typeName, isLoadAssembly)); }
private static Type GetTypeInternal(String typeName, Boolean isLoadAssembly) { // 基本获取 var type = Type.GetType(typeName); if (type != null) { return(type); } // 处理泛型 if (typeName[typeName.Length - 1] == '>') { return(GetGenericType(typeName, isLoadAssembly)); } // 处理数组 有可能是 aa [[ dddd ]] ,也有可能是 aa[dddd] if (typeName[typeName.Length - 1] == ']') { return(GetArrayType(typeName, isLoadAssembly)); } // 处理内嵌类型 // 尝试本程序集 var asms = new[] { AssemblyX.Create(Assembly.GetExecutingAssembly()), AssemblyX.Create(Assembly.GetCallingAssembly()), AssemblyX.Create(Assembly.GetEntryAssembly()) }; var loads = new List <AssemblyX>(); foreach (var asm in asms) { if (asm == null || loads.Contains(asm)) { continue; } loads.Add(asm); type = asm.GetType(typeName); if (type != null) { return(type); } } // 尝试所有程序集 foreach (var asm in AssemblyX.GetAssemblies()) { if (loads.Contains(asm)) { continue; } loads.Add(asm); type = asm.GetType(typeName); if (type != null) { return(type); } } // 尝试加载只读程序集 if (isLoadAssembly) { foreach (var asm in AssemblyX.ReflectionOnlyGetAssemblies()) { type = asm.GetType(typeName); if (type != null) { // 真实加载 //var file = asm.Asm.CodeBase; //if (String.IsNullOrEmpty(file)) // file = asm.Asm.Location; //else if (file.StartsWith("file:///")) // file = file.Substring("file:///".Length); // ASP.Net中不会锁定原始DLL文件 var file = asm.Asm.Location; try { type = null; var asm2 = Assembly.LoadFile(file); var type2 = AssemblyX.Create(asm2).GetType(typeName); if (type2 == null) { continue; } type = type2; if (XTrace.Debug) { XTrace.WriteLine("TypeX.GetType(\"{0}\")导致加载{1}", typeName, file); } } catch (Exception ex) { if (XTrace.Debug) { XTrace.WriteException(ex); } } return(type); } } } return(null); }