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(); public static string CustomDllName = ""; 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.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 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 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 { return new UpdateableProvider(); } } public static DeleteableProvider GetDeleteableProvider(ConnectionConfig currentConnectionConfig) where T : class, new() { if (currentConnectionConfig.DbType == DbType.Oracle) { return new OracleDeleteable(); } 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 { return new InsertableProvider(); } } 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 (!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, true).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); } var result = (T)Activator.CreateInstance(type, true); return result; } internal static Type GetCustomTypeByClass(string className) { var key = "Assembly_"+ CustomDllName+assembly.GetHashCode(); var newAssembly = new ReflectionInoCacheService().GetOrCreate(key, () => { try { 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); return type; } #endregion } }