Пример #1
0
        /// <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));
        }
Пример #2
0
        /// <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
        }
Пример #3
0
 /// <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));
 }
Пример #4
0
        /// <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));
        }
Пример #5
0
        /// <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);
                }
            }
        }
Пример #6
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);
        }
Пример #7
0
 /// <summary>根据名称获取类型</summary>
 /// <param name="typeName">类型名</param>
 /// <param name="isLoadAssembly">是否从未加载程序集中获取类型。使用仅反射的方法检查目标类型,如果存在,则进行常规加载</param>
 /// <returns></returns>
 public virtual Type GetType(String typeName, Boolean isLoadAssembly) => AssemblyX.GetType(typeName, isLoadAssembly);
Пример #8
0
        /// <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);
        }
Пример #9
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);
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #10
0
 /// <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));
 }
Пример #11
0
 /// <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));
 }
Пример #12
0
 /// <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));
 }
Пример #13
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);
        }