分層架構核心原則:**上層不依賴下層具體實現,而依賴抽象介面**。若 BLL 直接 new SqlDAL(),更換資料庫即須修改 BLL 程式碼並重新編譯,違反開放封閉原則。DI 容器讓具體型別在組態檔宣告,執行期動態解析,實現「可替換式」架構與並行開發。
傳統 Abstract Factory 需為每種 DAL 實作寫一個 Factory 類別(如 SqlDALFactory、AccessDALFactory),類別爆炸。.NET 反射機制允許單一 Factory 透過組件名稱動態載入型別,大幅簡化結構。

<appSettings>
<add key="DAL" value="" /> <!-- 如:NGuestBook.AccessDAL -->
<add key="BLL" value="" /> <!-- 如:NGuestBook.SimpleBLL -->
</appSettings>
封裝 HttpRuntime.Cache,支援檔案相依性(Web.config 變更自動失效):
public sealed class CacheAccess
{
public static void SaveToCache(string key, object obj, CacheDependency dep)
=> HttpRuntime.Cache.Insert(key, obj, dep);
public static object GetFromCache(string key)
=> HttpRuntime.Cache[key];
}
雙方法分別解析 DAL/BLL,邏輯對稱:
public sealed class DependencyInjector
{
public static object GetDALObject(string className)
{
// 1. 取得 DAL 組件名稱 (快取優先)
object dal = CacheAccess.GetFromCache("DAL");
if (dal == null) {
var dep = new CacheDependency(HttpContext.Current.Server.MapPath("Web.Config"));
dal = ConfigurationManager.AppSettings["DAL"];
CacheAccess.SaveToCache("DAL", dal, dep);
}
string dalName = (string)dal;
// 2. 取得具體型別實例 (快取優先)
object obj = CacheAccess.GetFromCache(className);
if (obj == null) {
var dep = new CacheDependency(HttpContext.Current.Server.MapPath("Web.Config"));
obj = Assembly.Load(dalName).CreateInstance(dalName + "." + className);
CacheAccess.SaveToCache(className, obj, dep);
}
return obj;
}
public static object GetBLLObject(string className) { /* 同理,鍵改為 "BLL" */ }
}
關鍵設計:雙層快取(組件名稱 + 實例),Web.config 為相依性觸發熱更新,Assembly.Load 載入組件,CreateInstance 建立具體型別。
DALFactory、BLLFactory 封裝介面轉型,呼叫端零耦合:
public sealed class DALFactory
{
public static IAdminDAL CreateAdminDAL() => (IAdminDAL)DependencyInjector.GetDALObject("AdminDAL");
public static IMessageDAL CreateMessageDAL() => (IMessageDAL)DependencyInjector.GetDALObject("MessageDAL");
public static ICommentDAL CreateCommentDAL() => (ICommentDAL)DependencyInjector.GetDALObject("CommentDAL");
}
public sealed class BLLFactory { /* 同理 */ }
public class AdminBLL : IAdminBLL
{
private readonly IAdminDAL dal = DALFactory.CreateAdminDAL(); // 唯一依賴抽象
public AdminInfo Login(string name, string pwd) => dal.GetByNameAndPassword(name, pwd);
// ...
}
Web.config 兩行組件名稱,全系統 DAL/BLL 實作無縫切換。Web.config 變更觸發快取失效,無需重啟 IIS 即可生效(ASP.NET 自動重啟應用程式域除外)。DependencyInjector 專責解析,Factory 專責型別轉換與對外介面。這是一個輕量級、生產可用的 IoC 容器雛形,展現了 .NET 反射與快取機制結合的實戰價值。