/// <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); } } } } } } }
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); }
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); }