NHibernate 延遲載入核心在於 **動態 Proxy 攔截器** 攔截屬性/方法存取,觸發 **LazyInitializer** 載入實體。本文基於 NHibernate 2.1.2 原始碼架構,完整剖析從 SessionFactory 建置、Proxy 建立、攔截處理到實體載入的全流程。

proxyfactory.factory_class 設定建立 IProxyFactoryFactory 實例 (預設 Castle / LinFu / Spring)use_proxy_validator=true (預設):載入實體中繼資料後,呼叫 ProxyValidator 驗證實體符合 Proxy 條件:
IProxyFactory,呼叫 PostInstantiate 記錄元資料:
EntityName、PersistentClass、Interfaces (含 INHibernateProxy)LazyInitializer 實例 (實作動態 Proxy 庫的攔截器介面),注入:
INHibernateProxy 作為 **Mixin 介面** 混入 Proxy,內部用於識別 Proxy 與取得 LazyInitializerObject 基類未覆寫方法 (GetType(), GetHashCode(), Equals(), ToString() — 若未 override)Dispose()_target != null) → 已載入直接返回session.Get(entityType, id)cache.Get(id)EntityPersister 具現化實體_target = loadedEntity_target 實體對應方法/屬性**INHibernateProxy 同時取得 Proxy 與實體
ISessionFactory sf = new Configuration().Configure().BuildSessionFactory();
using (ISession session = sf.OpenSession())
{
// 僅建立 Proxy,未觸發載入
MyUser proxy = session.Load(11);
Console.WriteLine(proxy.GetType().FullName); // NHibernate 產生的 Proxy 類別名
// 呼叫 override ToString() → 觸發載入
Console.WriteLine(proxy.ToString());
// 取得真實實體
NHibernate.Proxy.INHibernateProxy nhProxy = proxy as INHibernateProxy;
MyUser real = nhProxy.HibernateLazyInitializer.GetImplementation() as MyUser;
Console.WriteLine(real.GetType().FullName); // 真實 MyUser
Console.WriteLine(real.ToString());
}
sf.Close();

| Proxy 庫 | 優點 | 缺點 | 建議場景 |
|---|---|---|---|
| Castle DynamicProxy | 成熟穩定、效能佳、支援介面/類別 Proxy | 依賴較大 | 預設首選 |
| LinFu DynamicProxy | 輕量、無外部依賴 | 維護較少 | 嵌入式/輕量專案 |
| Spring.NET AOP Proxy | 整合 Spring 容器 | 需 Spring.NET 執行環境 | 已使用 Spring.NET 專案 |
FetchMode.Join、FetchMode.Subselect 或 HQL FETCH 預先載入。NHibernate 延遲載入本質:**動態 Proxy 攔截 → LazyInitializer 雙重檢查鎖載入 → 真實實體獨立存放 → 反射轉發**。理解 IProxyFactoryFactory、LazyInitializer、INHibernateProxy 三大核心介面職責,能精準診斷 LazyInitializationException、Proxy 驗證失敗、序列化失效等疑難雜症,並在效能調優時做出正確的 Fetch Strategy 決策。