示例#1
0
        /// <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);
                                }
                            }
                        }
                    }
                }
            }
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }