早期專案若需支援多資料庫(SQL Server → Oracle → MySQL),往往面臨大量程式碼重寫的惡夢。資料工廠模式結合反射機制,讓資料存取層(DAL)實現真正的「零程式碼修改、零重新編譯、單純部署 DLL」的無縫切換。本文以經典 PetShop 3.0 架構為藍本,完整解析實作細節。
┌─────────────┐ 介面契約 ┌──────────────────┐
│ BLL 業務層 │ ◄──────────────► │ IDAL 介面組件 │
└─────────────┘ (ICategory等) └────────┬─────────┘
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ SQLServerDAL.dll │ │ OracleDAL.dll │ │ MySqlDAL.dll │
│ 實作 IDAL 介面 │ │ 實作 IDAL 介面 │ │ 實作 IDAL 介面 │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
└─────────────────────┼─────────────────────┘
▼
┌─────────────────────┐
│ DALFactory 工廠類 │
│ 反射動態建立實例 │
└─────────────────────┘
namespace PetShop.IDAL
{
public interface ICategory
{
IList GetCategories();
CategoryInfo GetCategory(string categoryId);
void InsertCategory(CategoryInfo category);
// ... 其他業務方法
}
}
每個資料庫專案結構相同,僅實作細節不同:
// PetShop.SQLServerDAL/Category.cs
namespace PetShop.SQLServerDAL
{
public class Category : IDAL.ICategory
{
// SQL Server 專用 T-SQL、SqlClient 實作
}
}
// PetShop.OracleDAL/Category.cs
namespace PetShop.OracleDAL
{
public class Category : IDAL.ICategory
{
// Oracle 專用 PL/SQL、OracleClient 實作
}
}
<appSettings>
<!-- 切換資料庫只需修改此處 -->
<add key="WebDAL" value="PetShop.SQLServerDAL" />
<add key="OrdersDAL" value="PetShop.SQLServerDAL" />
<!-- 切換至 Oracle -->
<!-- <add key="WebDAL" value="PetShop.OracleDAL" /> -->
<!-- <add key="OrdersDAL" value="PetShop.OracleDAL" /> -->
<!-- 切換至 MySQL -->
<!-- <add key="WebDAL" value="PetShop.MySqlDAL" /> -->
</appSettings>
namespace PetShop.DALFactory
{
public sealed class DataAccess
{
private static readonly string _dalPath = ConfigurationManager.AppSettings["WebDAL"];
public static IDAL.ICategory CreateCategory()
{
string className = _dalPath + ".Category"; // 如 "PetShop.SQLServerDAL.Category"
// 反射載入組件並建立實例,回傳介面型別
return (IDAL.ICategory)Assembly.Load(_dalPath).CreateInstance(className);
}
// 其他 CreateXxx 方法同理...
}
}
namespace PetShop.BLL
{
public class Category
{
private static readonly IDAL.ICategory _dal = DALFactory.DataAccess.CreateCategory();
public IList GetCategories()
{
return _dal.GetCategories(); // 僅呼叫介面方法
}
}
}
PetShop.MySqlDAL 專案,參考 PetShop.IDAL 並實作所有介面PetShop.MySqlDAL.dll 部署至 Bin 目錄web.config:<add key="WebDAL" value="PetShop.MySqlDAL" />// 反模式:違反開放封閉原則
switch (webDal)
{
case "SQLServerDAL": return new SqlServerDALFactory();
case "OracleDAL": return new OracleDALFactory();
case "MySqlDAL": return new MySqlDALFactory(); // 新增資料庫必須修改此處並重新編譯
default: return new SqlServerDALFactory();
}
反射工廠優勢:新增資料庫只需新增 DLL + 修改組態,既有程式碼完全不動,完美符合開放封閉原則(OCP)。
connectionStrings 區段,不同資料庫獨立維護連線資訊此架構已在無數企業級產品驗證,是 .NET 多資料庫支援的黃金標準模式。