namespace DBHelper {
public interface IDAL {
DataSet GetDataSet(string query);
int ExecuteNonQuery(string sql);
object ExecuteScalar(string sql);
}
}
// SQL Server 實現
public class SqlHelper : IDAL {
public DataSet GetDataSet(string query) {
using (var conn = new SqlConnection(Config.SqlConnStr))
using (var da = new SqlDataAdapter(query, conn)) {
var ds = new DataSet(); da.Fill(ds); return ds;
}
}
// ... ExecuteNonQuery, ExecuteScalar
}
// Oracle 實現
public class OracleHelper : IDAL {
public DataSet GetDataSet(string query) {
using (var conn = new OracleConnection(Config.OracleConnStr))
using (var da = new OracleDataAdapter(query, conn)) {
var ds = new DataSet(); da.Fill(ds); return ds;
}
}
// ...
}
public static class DALFactory {
private static IDAL _instance;
private static readonly object _lock = new object();
public static IDAL Instance {
get {
if (_instance != null) return _instance;
lock (_lock) {
if (_instance == null) {
string asmName = ConfigurationManager.AppSettings["DALAssembly"]; // 如 "DBHelper"
string typeName = ConfigurationManager.AppSettings["DALType"]; // 如 "DBHelper.SqlHelper"
Assembly asm = Assembly.Load(asmName);
_instance = (IDAL)asm.CreateInstance(typeName);
}
return _instance;
}
}
}
}
<appSettings>
<add key="DALAssembly" value="DBHelper" />
<add key="DALType" value="DBHelper.SqlHelper" />
<add key="SqlConnStr" value="Server=.;Database=Northwind;Integrated Security=true" />
<add key="OracleConnStr" value="Data Source=ORCL;User Id=scott;Password=tiger" />
</appSettings>
var dal = DALFactory.Instance;
var ds = dal.GetDataSet("SELECT * FROM Customers WHERE Country = 'Germany'");
| 需求 | 擴展方案 |
|---|---|
| 多租戶/多數據庫 | 工廠返回 IDAL 字典,Key 為租戶/數據庫標識 |
| 依賴注入 (DI) 容器 | 註冊 IDAL 實現,構造函數注入連接字符串,生命週期 Scoped/Transient |
| 讀寫分離 | 接口擴展 IReadDAL/IWriteDAL,工廠路由 |
| 動態切換無重啟 | FileSystemWatcher 監聽配置變更,重置單例/容器註冊 |
| 性能計數/日誌 | 裝飾器模式包裝 IDAL,攔截方法記錄耗時/參數 |
「接口 + 反射 + 配置」模式以極低耦合成本實現數據庫訪問層的多態切換。現代 .NET Core 應用優先採用 EF Core Provider 機制或 DI 容器註冊多實現,但該模式在遺留系統遷移、插件化架構、動態多數據庫路由場景仍具備極高實用價值。