using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace SqlSugar { public class InstanceFactory { static Assembly assembly = Assembly.GetExecutingAssembly(); static Dictionary typeCache = new Dictionary(); private static string _CustomDllName = ""; private static List CustomDlls = new List(); public static Assembly[] CustomAssemblies = new Assembly[]{}; public static string CustomDllName { get { return _CustomDllName; } set { if (!CustomDlls.Contains(value)) { CustomDlls.Add(value); } _CustomDllName = value; } } public static string CustomDbName = ""; public static string CustomNamespace = ""; public static bool NoCache = false; public static bool IsWebFrom = false; public static void RemoveCache() { typeCache = new Dictionary(); } #region Queryable public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) { if (currentConnectionConfig.DbType == DbType.SqlServer) { return new SqlServerQueryable(); } else if (currentConnectionConfig.DbType == DbType.MySql) { return new MySqlQueryable(); } else if (currentConnectionConfig.DbType == DbType.Sqlite) { return new SqliteQueryable(); } else if (currentConnectionConfig.DbType == DbType.PostgreSQL) { return new PostgreSQLQueryable(); } else { string className = "Queryable"; className = GetClassName(currentConnectionConfig.DbType.ToString(), className); ISugarQueryable result = CreateInstance>(className); return result; } } public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) { if (currentConnectionConfig.DbType == DbType.SqlServer) { return new SqlServerQueryable(); } else { string className = "Queryable"; className = GetClassName(currentConnectionConfig.DbType.ToString(), className); ISugarQueryable result = CreateInstance>(className); return result; } } public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) { if (currentConnectionConfig.DbType == DbType.SqlServer) { return new SqlServerQueryable(); } else { string className = "Queryable"; className = GetClassName(currentConnectionConfig.DbType.ToString(), className); ISugarQueryable result = CreateInstance>(className); return result; } } public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) { string className = "Queryable"; className = GetClassName(currentConnectionConfig.DbType.ToString(), className); ISugarQueryable result = CreateInstance>(className); return result; } public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) { string className = "Queryable"; className = GetClassName(currentConnectionConfig.DbType.ToString(), className); ISugarQueryable result = CreateInstance>(className); return result; } public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) { string className = "Queryable"; className = GetClassName(currentConnectionConfig.DbType.ToString(), className); ISugarQueryable result = CreateInstance>(className); return result; } public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) { string className = "Queryable"; className = GetClassName(currentConnectionConfig.DbType.ToString(), className); ISugarQueryable result = CreateInstance>(className); return result; } public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) { string className = "Queryable"; className = GetClassName(currentConnectionConfig.DbType.ToString(), className); ISugarQueryable result = CreateInstance>(className); return result; } #region 9-12 public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) { string className = "Queryable"; className = GetClassName(currentConnectionConfig.DbType.ToString(), className); ISugarQueryable result = CreateInstance>(className); return result; } public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) { string className = "Queryable"; className = GetClassName(currentConnectionConfig.DbType.ToString(), className); ISugarQueryable result = CreateInstance>(className); return result; } public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) { string className = "Queryable"; className = GetClassName(currentConnectionConfig.DbType.ToString(), className); ISugarQueryable result = CreateInstance>(className); return result; } public static ISugarQueryable GetQueryable(ConnectionConfig currentConnectionConfig) { string className = "Queryable"; className = GetClassName(currentConnectionConfig.DbType.ToString(), className); ISugarQueryable result = CreateInstance>(className); return result; } #endregion #endregion public static QueryBuilder GetQueryBuilderWithContext(ISqlSugarClient db) { if (db is SqlSugarClient) { db = (db as SqlSugarClient).Context; } else if (db is SqlSugarScope) { db = (db as SqlSugarScope).ScopedContext.Context; } if (!(db is SqlSugarProvider)) { db = new SqlSugarClient(db.CurrentConnectionConfig).Context; } var QueryBuilder = InstanceFactory.GetQueryBuilder(db.CurrentConnectionConfig); QueryBuilder.Context = (SqlSugarProvider)db; QueryBuilder.Builder = InstanceFactory.GetSqlbuilder(db.CurrentConnectionConfig); QueryBuilder.Builder.Context = (SqlSugarProvider)db; return QueryBuilder; } public static QueryBuilder GetQueryBuilder(ConnectionConfig currentConnectionConfig) { if (currentConnectionConfig.DbType == DbType.SqlServer) { return new SqlServerQueryBuilder(); } else if (currentConnectionConfig.DbType == DbType.MySql) { return new MySqlQueryBuilder(); } else { QueryBuilder result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "QueryBuilder")); return result; } } public static InsertBuilder GetInsertBuilder(ConnectionConfig currentConnectionConfig) { InsertBuilder result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "InsertBuilder")); return result; } public static UpdateBuilder GetUpdateBuilder(ConnectionConfig currentConnectionConfig) { UpdateBuilder result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "UpdateBuilder")); return result; } public static DeleteBuilder GetDeleteBuilder(ConnectionConfig currentConnectionConfig) { DeleteBuilder result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "DeleteBuilder")); return result; } public static ILambdaExpressions GetLambdaExpressions(ConnectionConfig currentConnectionConfig) { if (currentConnectionConfig.DbType == DbType.SqlServer) { return new SqlServerExpressionContext(); } else if (currentConnectionConfig.DbType == DbType.MySql) { return new MySqlExpressionContext(); } else { ILambdaExpressions result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "ExpressionContext")); return result; } } public static ISqlBuilder GetSqlBuilderWithContext(ISqlSugarClient db) { var result= GetQueryBuilderWithContext(db).Builder; return result; } public static ISqlBuilder GetSqlbuilder(ConnectionConfig currentConnectionConfig) { if (currentConnectionConfig.DbType == DbType.SqlServer) { return new SqlServerBuilder(); } else if (currentConnectionConfig.DbType == DbType.MySql) { return new MySqlBuilder(); } else { ISqlBuilder result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "Builder")); return result; } } public static UpdateableProvider GetUpdateableProvider(ConnectionConfig currentConnectionConfig) where T : class, new() { if (currentConnectionConfig.DbType == DbType.Oracle) { return new OracleUpdateable(); } else if (IsCustomDb(currentConnectionConfig)) { var name = "SqlSugar." + currentConnectionConfig.DbType + "." + currentConnectionConfig.DbType + "Updateable`1"; var type = GetCustomTypeByClass(name); if (type == null) { return new UpdateableProvider(); } else { return (UpdateableProvider)Activator.CreateInstance(type, true); } } else { return new UpdateableProvider(); } } public static DeleteableProvider GetDeleteableProvider(ConnectionConfig currentConnectionConfig) where T : class, new() { if (currentConnectionConfig.DbType == DbType.Oracle) { return new OracleDeleteable(); } else if (IsCustomDb(currentConnectionConfig)) { var name = "SqlSugar." + currentConnectionConfig.DbType + "." + currentConnectionConfig.DbType + "Deleteable`1"; var type = GetCustomTypeByClass(name); if (type == null) { return new DeleteableProvider(); } else { return (DeleteableProvider)Activator.CreateInstance(type, true); } } else { return new DeleteableProvider(); } } public static InsertableProvider GetInsertableProvider(ConnectionConfig currentConnectionConfig) where T : class, new() { if (currentConnectionConfig.DbType == DbType.Oracle) { return new OracleInsertable(); } else if (currentConnectionConfig.DbType == DbType.PostgreSQL) { return new PostgreSQLInserttable(); } else if (currentConnectionConfig.DbType == DbType.Kdbndp) { return new KdbndpInserttable(); } else if (currentConnectionConfig.DbType == DbType.Oscar) { return new KdbndpInserttable(); } else if (IsCustomDb(currentConnectionConfig)) { var name = "SqlSugar." + currentConnectionConfig.DbType + "." + currentConnectionConfig.DbType + "Insertable`1"; var type = GetCustomTypeByClass(name); if (type == null) { return new InsertableProvider(); } else { return (InsertableProvider)Activator.CreateInstance(type, true); } } else { return new InsertableProvider(); } } private static bool IsCustomDb(ConnectionConfig currentConnectionConfig) { return currentConnectionConfig.DbType != DbType.SqlServer && currentConnectionConfig.DbType != DbType.Dm && currentConnectionConfig.DbType != DbType.Oscar && currentConnectionConfig.DbType != DbType.Access && currentConnectionConfig.DbType != DbType.QuestDB && currentConnectionConfig.DbType != DbType.MySql && currentConnectionConfig.DbType != DbType.Oracle && currentConnectionConfig.DbType != DbType.PostgreSQL && currentConnectionConfig.DbType != DbType.ClickHouse && currentConnectionConfig.DbType != DbType.GBase && currentConnectionConfig.DbType != DbType.Sqlite && GetCustomTypeByClass("SqlSugar." + currentConnectionConfig.DbType + "." + currentConnectionConfig.DbType + "Provider") != null; } public static IDbBind GetDbBind(ConnectionConfig currentConnectionConfig) { if (currentConnectionConfig.DbType == DbType.SqlServer) { return new SqlServerDbBind(); } else if (currentConnectionConfig.DbType == DbType.MySql) { return new MySqlDbBind(); } else { IDbBind result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "DbBind")); return result; } } public static IDbMaintenance GetDbMaintenance(ConnectionConfig currentConnectionConfig) { IDbMaintenance result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "DbMaintenance")); return result; } public static IDbFirst GetDbFirst(ConnectionConfig currentConnectionConfig) { IDbFirst result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "DbFirst")); return result; } public static ICodeFirst GetCodeFirst(ConnectionConfig currentConnectionConfig) { ICodeFirst result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "CodeFirst")); return result; } public static IAdo GetAdo(ConnectionConfig currentConnectionConfig) { if (currentConnectionConfig.DbType == DbType.SqlServer) { return new SqlServerProvider(); } else { IAdo result = CreateInstance(GetClassName(currentConnectionConfig.DbType.ToString(), "Provider")); return result; } } private static string GetClassName(string type, string name) { if (type == "MySqlConnector") { return "SqlSugar.MySqlConnector.MySql" + name; } else if (type == "Access") { return "SqlSugar.Access.Access" + name; } else if (type == "ClickHouse") { return "SqlSugar.ClickHouse.ClickHouse" + name; } else if (type == "GBase") { return "SqlSugar.GBase.GBase" + name; } else if (type == "Odbc") { return "SqlSugar.Odbc.Odbc" + name; } else if (type == "Custom") { return CustomNamespace + "."+CustomDbName + name; } else if (type == "HANA") { return InstanceFactory.CustomDllName + "." + type + name; } else if (type == "DB2") { return "SqlSugar.DB2."+ type+ name; } else { //if (!string.IsNullOrEmpty(CustomDllName)) //{ // type = CustomDllName; //} return UtilConstants.AssemblyName + "." + type + name; } } #region CreateInstance private static Restult CreateInstance(string className) { return CreateInstance(className, typeof(T)); } private static Restult CreateInstance(string className) { return CreateInstance(className, typeof(T), typeof(T2)); } private static Restult CreateInstance(string className) { return CreateInstance(className, typeof(T), typeof(T2), typeof(T3)); } private static Restult CreateInstance(string className) { return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4)); } private static Restult CreateInstance(string className) { return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5)); } private static Restult CreateInstance(string className) { return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6)); } private static Restult CreateInstance(string className) { return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7)); } private static Restult CreateInstance(string className) { return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8)); } #region 9-12 private static Restult CreateInstance(string className) { return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9)); } private static Restult CreateInstance(string className) { return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10)); } private static Restult CreateInstance(string className) { return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11)); } private static Restult CreateInstance(string className) { return CreateInstance(className, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9), typeof(T10), typeof(T11), typeof(T12)); } #endregion private static Restult CreateInstance(string className, params Type[] types) { try { if (NoCache) { return NoCacheGetCacheInstance(className, types); } else { return GetCacheInstance(className, types); } } catch { NoCache = true; return NoCacheGetCacheInstance(className, types); } } private static Restult GetCacheInstance(string className, Type[] types) { var cacheKey = className + string.Join(",", types.Select(it => it.FullName)); Type type=null; if (typeCache.ContainsKey(cacheKey)) { type = typeCache[cacheKey]; } else { lock (typeCache) { if (string.IsNullOrEmpty(CustomDllName)) { type = Type.GetType(className + "`" + types.Length, true).MakeGenericType(types); } else { var custom = GetCustomTypeByClass(className + "`" + types.Length); if (custom != null) { type = custom.MakeGenericType(types); } if (type == null) { type = Type.GetType(className + "`" + types.Length, true).MakeGenericType(types); } } Check.ArgumentNullException(type, string.Format(ErrorMessage.ObjNotExist, className)); if (!typeCache.ContainsKey(cacheKey)) { typeCache.Add(cacheKey, type); } } } var result = (Restult)Activator.CreateInstance(type, true); return result; } private static Restult NoCacheGetCacheInstance(string className, Type[] types) { Type type = null; if (string.IsNullOrEmpty(CustomDllName)) { type = Type.GetType(className + "`" + types.Length, true).MakeGenericType(types); } else { var custom = GetCustomTypeByClass(className + "`" + types.Length); if (custom != null) { type = custom.MakeGenericType(types); } if (type == null) { type = Type.GetType(className + "`" + types.Length)?.MakeGenericType(types); if (type == null) { type = GetCustomDbType(className + "`" + types.Length, type).MakeGenericType(types); } } } var result = (Restult)Activator.CreateInstance(type, true); return result; } public static T CreateInstance(string className) { try { if (NoCache) { return NoCacheGetCacheInstance(className); } else { return GetCacheInstance(className); } } catch { return NoCacheGetCacheInstance(className); } } private static T GetCacheInstance(string className) { Type type; if (typeCache.ContainsKey(className)) { type = typeCache[className]; } else { lock (typeCache) { if (string.IsNullOrEmpty(CustomDllName)) { type = assembly.GetType(className); } else { type= GetCustomTypeByClass(className); if (type == null) { type = assembly.GetType(className); } } Check.ArgumentNullException(type, string.Format(ErrorMessage.ObjNotExist, className)); if (!typeCache.ContainsKey(className)) { typeCache.Add(className, type); } } } var result = (T)Activator.CreateInstance(type, true); return result; } private static T NoCacheGetCacheInstance(string className) { Type type = null; if (string.IsNullOrEmpty(CustomDllName)) { type=assembly.GetType(className); } else { type = GetCustomTypeByClass(className); } if (type == null) { type = GetCustomDbType(className, type); } var result = (T)Activator.CreateInstance(type, true); return result; } private static Type GetCustomDbType(string className, Type type) { if (className.Replace(".", "").Length + 1 == className.Length) { var array = className.Split('.'); foreach (var item in UtilMethods.EnumToDictionary()) { if (array.Last().StartsWith(item.Value.ToString())) { var newName = array.First() + "." + item.Value.ToString() + "." + array.Last(); type = GetCustomTypeByClass(newName); break; } } } return type; } internal static Type GetCustomTypeByClass(string className) { Type type = null; foreach (var item in CustomDlls.ToArray()) { if (type == null) { type = GetCustomTypeByClass(className, item); } if(type != null) { break; } } return type; } internal static Type GetCustomTypeByClass(string className,string customDllName) { var key = "Assembly_" + customDllName + assembly.GetHashCode(); var newAssembly = new ReflectionInoCacheService().GetOrCreate(key, () => { try { if (CustomAssemblies?.Any(it => it.FullName.StartsWith(customDllName))==true) { return CustomAssemblies?.First(it => it.FullName.StartsWith(customDllName)); } var path = Assembly.GetExecutingAssembly().Location; if (path.HasValue()) { path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(path), customDllName + ".dll"); } if (path.HasValue() && FileHelper.IsExistFile(path)) { return Assembly.LoadFrom(path); } else { if (IsWebFrom) { string newpath = (System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\" + customDllName + ".dll").Replace("file:\\", ""); return Assembly.LoadFrom(newpath); } return Assembly.LoadFrom(customDllName + ".dll"); } } catch { var message = "Not Found " + customDllName + ".dll"; Check.Exception(true, message); return null; } }); Type type = newAssembly.GetType(className); if (type == null) { type = assembly.GetType(className); } return type; } internal static Type GetCustomTypeByClass(string className) { Type type = null; foreach (var item in CustomDlls.ToArray()) { if (type == null) { type = GetCustomTypeByClass(className, item); } if (type != null) { break; } } return type; } internal static Type GetCustomTypeByClass(string className,string customDllName) { var key = "Assembly_" + customDllName + assembly.GetHashCode(); var newAssembly = new ReflectionInoCacheService().GetOrCreate(key, () => { try { if (CustomAssemblies?.Any(it => it.FullName.StartsWith(customDllName)) == true) { return CustomAssemblies?.First(it => it.FullName.StartsWith(customDllName)); } var path = Assembly.GetExecutingAssembly().Location; if (path.HasValue()) { path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(path), customDllName + ".dll"); } if (path.HasValue() && FileHelper.IsExistFile(path)) { return Assembly.LoadFrom(path); } else { if (IsWebFrom) { string newpath = (System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\" + customDllName + ".dll").Replace("file:\\", ""); return Assembly.LoadFrom(newpath); } return Assembly.LoadFrom(customDllName + ".dll"); } } catch { var message = "Not Found " + customDllName + ".dll"; Check.Exception(true, message); return null; } }); Type typeArgument = typeof(T); string fullTypeName = className + "[[" + typeArgument.FullName+","+ typeArgument.Assembly.FullName+ "]]"; Type type = newAssembly.GetType(fullTypeName); return type; } #endregion } }