以下為 SqlRepoEx.MsSql.ServiceCollection 程式碼
public static IServiceCollection AddSqlRepo(this IServiceCollection serviceCollection)
{
serviceCollection.AddTransient<IRepositoryFactory, RepositoryFactory>();
serviceCollection.AddTransient<IStatementFactoryProvider, MsSqlStatementFactoryProvider>();
serviceCollection.AddTransient<IEntityMapper, DataReaderEntityMapper>();
serviceCollection.AddTransient<IWritablePropertyMatcher, WritablePropertyMatcher>();
serviceCollection.AddTransient<ISqlLogger, SqlLogger>();
serviceCollection.AddTransient<IStatementExecutor, MsSqlStatementExecutor>();
return serviceCollection;
}
本質上,其處出現的介面及其實現類,其介面的實現類都是可以自定義的
其中,IEntityMapper,IStatementExecutor兩個介面去擴充套件更具有意義。
其他的高階擴充套件暫時未開放,不作介紹
我們以Dapper的擴充套件為例,參照實現,擴充套件自己定製的功能
一、IEntityMapper 例項對映器介面,其功能主要是 將資料提供者IDataReader中的資料,轉換到應用程式可用的資料或資料集中
其介面定義為
/// <summary> /// 例項對映器介面,將IDataReader中的資料轉換成TEntity型別例項 /// 使用者可以實現自已的對映器,來實現業務中資料與TEntity類之間的轉換 /// 預設的對映器為 DataReaderEntityMapper ,SqlRepoEx中還實現了 /// 與Dapper互動的DapperEntityMapper。 /// IEntityMapper必需實現並指定,以供 SqlRepoEx 使用。 /// </summary> public interface IEntityMapper { IEnumerable<TEntity> Map<TEntity>(IDataReader reader) where TEntity : class, new(); List<TEntity> MapList<TEntity>(IDataReader reader) where TEntity : class, new(); TLEntity MapEntityList<TLEntity, T>(IDataReader reader) where TLEntity : List<T>, new() where T : class, new(); }
SqlRepoEx.Adapter.Dapper中的實現
/// <summary> /// 支援 Dapper 的例項對映器 /// https://github.com/StackExchange/Dapper /// </summary> public class DapperEntityMapper : IEntityMapper { /// <summary> /// 從訪問關聯式資料庫的資料提供者IDataReader。讀取一個或多個正向的結果集流,並將此 /// 資料集對映到DTO列表中。 /// </summary> /// <typeparam name="TEntity">DTO 型別</typeparam> /// <param name="reader">訪問關聯式資料庫的資料提供者</param> /// <returns></returns> public IEnumerable<TEntity> Map<TEntity>(IDataReader reader) where TEntity : class, new() { return reader.Parse<TEntity>().ToList(); } /// <summary> /// 從訪問關聯式資料庫的資料提供者IDataReader。讀取一個或多個正向的結果集流,並將此 /// 資料集對映到DTO列表中。 /// </summary> /// <typeparam name="TLEntity">List DTO 型別</typeparam> /// <typeparam name="T">DTO 型別</typeparam> /// <param name="reader">訪問關聯式資料庫的資料提供者</param> /// <returns></returns> public TLEntity MapEntityList<TLEntity, T>(IDataReader reader) where TLEntity : List<T>, new() where T : class, new() { var list = new TLEntity(); list.AddRange(reader.Parse<T>()); return list; } /// <summary> /// 從訪問關聯式資料庫的資料提供者IDataReader。讀取一個或多個正向的結果集流,並將此 /// 資料集對映到DTO列表中。 /// </summary> /// <typeparam name="TEntity">DTO 型別</typeparam> /// <param name="reader">訪問關聯式資料庫的資料提供者</param> /// <returns></returns> public List<TEntity> MapList<TEntity>(IDataReader reader) where TEntity : class, new() { return reader.Parse<TEntity>().ToList(); } }
二、IStatementExecutor 語句執行器介面,其功能是 SqlRepoEx 執行Sql的各種操作
其介面定義為
/// <summary> /// SQL語句執行器(必需)。SqlRepoEx需要此介面的實現類來執行Sql語句。 /// 使用者可自定義此介面實現類,以達到所需執行效果。 /// </summary> public interface IStatementExecutor { int ExecuteNonQuery(string sql); Task<int> ExecuteNonQueryAsync(string sql); int ExecuteNonQueryStoredProcedure(string name, params ParameterDefinition[] parameterDefinitions); Task<int> ExecuteNonQueryStoredProcedureAsync(string name, params ParameterDefinition[] parameterDefinitions); IDataReader ExecuteReader(string sql); Task<IDataReader> ExecuteReaderAsync(string sql); IDataReader ExecuteStoredProcedure(string name, params ParameterDefinition[] parametersDefinitions); Task<IDataReader> ExecuteStoredProcedureAsync(string name, params ParameterDefinition[] parametersDefinitions); IStatementExecutor UseConnectionProvider(IConnectionProvider connectionProvider); }
SqlRepoEx.Adapter.Dapper中的實現
/// <summary> /// Dapper語句執行器 /// https://github.com/StackExchange/Dapper /// </summary> public class DapperStatementExecutor : IStatementExecutor { private IConnectionProvider connectionProvider; private DbConnection dbConnection; private DynamicParameters TurnParameters(ParameterDefinition[] parameterDefinitions) { if (parameterDefinitions == null) { return null; } if (parameterDefinitions.Length == 0) { return null; } var p = new DynamicParameters(); foreach (var pd in parameterDefinitions) { p.Add(pd.Name, pd.Value, pd.DbType, pd.Direction, pd.Size); } return p; } /// <summary> /// Dapper語句執行器構造 /// </summary> /// <param name="connectionProvider">資料連線提供者</param> public DapperStatementExecutor(IConnectionProvider connectionProvider) { this.connectionProvider = connectionProvider; this.dbConnection = connectionProvider.GetDbConnection; } /// <summary> /// 執行並返回 ParameterDirection.ReturnValue中的值。 /// </summary> /// <param name="sql">需要執行的sql</param> /// <returns></returns> public int ExecuteNonQuery(string sql) { return dbConnection.Execute(sql); } /// <summary> /// 非同步執行並返回 ParameterDirection.ReturnValue中的值。 /// </summary> /// <param name="sql">需要執行的sql</param> /// <returns></returns> public Task<int> ExecuteNonQueryAsync(string sql) { return dbConnection.ExecuteAsync(sql); } /// <summary> /// 執行指定儲存過程,並返回 ParameterDirection.ReturnValue中的值。 /// </summary> /// <param name="name">儲存過程名</param> /// <param name="parameterDefinitions">儲存過程引數列表</param> /// <returns>返回 ParameterDirection.ReturnValue 中的值</returns> public int ExecuteNonQueryStoredProcedure(string name, params ParameterDefinition[] parameterDefinitions) { var args = TurnParameters(parameterDefinitions); return dbConnection.Execute(name, args, commandType: CommandType.StoredProcedure); } /// <summary> /// 非同步執行指定儲存過程,並返回 ParameterDirection.ReturnValue中的值。 /// </summary> /// <param name="name">儲存過程名</param> /// <param name="parameterDefinitions">儲存過程引數列表</param> /// <returns>返回 ParameterDirection.ReturnValue 中的值</returns> public Task<int> ExecuteNonQueryStoredProcedureAsync(string name, params ParameterDefinition[] parameterDefinitions) { var args = TurnParameters(parameterDefinitions); return dbConnection.ExecuteAsync(name, args, commandType: CommandType.StoredProcedure); } /// <summary> /// 執行指定sql,並以IDataReader形式返回。 /// </summary> /// <param name="sql">需要執行的sql</param> /// <returns></returns> public IDataReader ExecuteReader(string sql) { return dbConnection.ExecuteReader(sql); } /// <summary> /// 非同步執行指定sql,並以IDataReader形式返回。 /// </summary> /// <param name="sql">需要執行的sql</param> /// <returns></returns> public Task<IDataReader> ExecuteReaderAsync(string sql) { return dbConnection.ExecuteReaderAsync(sql); } /// <summary> /// 執行指定儲存過程,並以IDataReader形式返回。 /// </summary> /// <param name="name">儲存過程名</param> /// <param name="parametersDefinitions">引數列表</param> /// <returns></returns> public IDataReader ExecuteStoredProcedure(string name, params ParameterDefinition[] parametersDefinitions) { var args = TurnParameters(parametersDefinitions); return dbConnection.ExecuteReader(name, args, commandType: CommandType.StoredProcedure); } /// <summary> /// 非同步執行指定儲存過程,並以IDataReader形式返回。 /// </summary> /// <param name="name">儲存過程名</param> /// <param name="parametersDefinitions">引數列表</param> /// <returns></returns> public Task<IDataReader> ExecuteStoredProcedureAsync(string name, params ParameterDefinition[] parametersDefinitions) { var args = TurnParameters(parametersDefinitions); return dbConnection.ExecuteReaderAsync(name, args, commandType: CommandType.StoredProcedure); } /// <summary> /// 指定資料連線提供者 /// </summary> /// <param name="connectionProvider">資料連線提供者</param> /// <returns></returns> public IStatementExecutor UseConnectionProvider(IConnectionProvider connectionProvider) { this.connectionProvider = connectionProvider; return this; } }