internal static ConstructorInfo GetConstructorInfo(this Type type, params object[] parameters)
        {
            var key = type.FullName + string.Join("", parameters?.Select(x => x.GetType()));

            if (ConstructorInfos.ContainsKey(key))
            {
                return(ConstructorInfos.Get(key));
            }
#if !NETSTANDARD1_3
            return(ConstructorInfos.GetOrAdd(key, parameters == null ? type.GetConstructor(Type.EmptyTypes) : type.GetConstructor(parameters.Select(x => x.GetType()).ToArray())));
#else
            ConstructorInfo constructor = null;

            foreach (var cr in type.GetTypeInfo().DeclaredConstructors)
            {
                var index = 0;
                var args  = cr.GetParameters();
                if (args.Length == parameters.Length)
                {
                    var apply = true;
                    foreach (var pr in args)
                    {
                        var prType    = pr.ParameterType;
                        var paramType = parameters[index].GetType();

                        if (prType != paramType)
                        {
                            try
                            {
                                Convert.ChangeType(parameters[index], prType);
                            }
                            catch
                            {
                                apply = false;
                                break;
                            }
                        }
                        index++;
                    }
                    if (apply)
                    {
                        constructor = cr;
                    }
                }
            }
            return(ConstructorInfos.GetOrAdd(key, constructor));
#endif
        }
        internal static Type GetFastType(this string typeName, string assembly)
        {
            if (string.IsNullOrEmpty(assembly))
            {
                throw new Exception("AssemblyName cannot be empty");
            }

            if (!assembly.ToLower().EndsWith(".dll"))
            {
                assembly += ".dll";
            }
            var key = typeName + assembly;

            if (CachedStringTypes.ContainsKey(key))
            {
                return(CachedStringTypes.Get(key));
            }

            var type = Type.GetType($"{typeName}, {assembly.Substring(0, assembly.ToLower().IndexOf(".dll"))}");

            if (type != null)
            {
                if (!CachedAssembly.ContainsKey(assembly))
                {
                    CachedAssembly.TryAdd(assembly, type.Assembly);
                }
                return(CachedStringTypes.GetOrAdd(key, type));
            }
            else
            if (!CachedAssembly.ContainsKey(assembly))
            {
                CachedAssembly.TryAdd(assembly, Assembly.LoadFrom(assembly));
            }

            return(CachedStringTypes.GetOrAdd(key, CachedAssembly.Get(assembly).GetType(typeName, true, true)));
        }
        internal static ConstructorInfo GetConstructorInfo(this Type type, params object[] parameters)
        {
            IEnumerable <ConstructorInfo> constructors;
            var key = type.FullName + string.Join("", parameters?.Select(x => x.GetType()));

            if (ConstructorInfo.ContainsKey(key))
            {
                return(ConstructorInfo.Get(key));
            }

#if !NETSTANDARD1_3
            constructors = type.GetConstructors();
#else
            constructors = type.GetTypeInfo().DeclaredConstructors;
#endif
            ConstructorInfo constructor = null;
            foreach (var cr in constructors)
            {
                var index = 0;
                var args  = cr.GetParameters();
                if (args.Length == parameters.Length)
                {
                    var apply = true;
                    foreach (var pr in args)
                    {
                        var prType    = pr.ParameterType;
                        var paramType = parameters[index].GetType();

                        if (prType != paramType)
                        {
                            try
                            {
                                if ((prType.IsInternalType() && paramType.IsInternalType()))
                                {
                                    Convert.ChangeType(parameters[index], prType);
                                }
                                else
                                {
                                    if (prType.GetTypeInfo().IsInterface&& paramType.GetTypeInfo().IsAssignableFrom(prType.GetTypeInfo()))
                                    {
                                        continue;
                                    }
                                    else
                                    {
                                        apply = false;
                                        break;
                                    }
                                }
                            }
                            catch
                            {
                                apply = false;
                                break;
                            }
                        }
                        index++;
                    }
                    if (apply)
                    {
                        constructor = cr;
                    }
                }
            }

            return(ConstructorInfo.GetOrAdd(key, constructor));
        }