ObjectBuilder2 (OB2) 是微軟模式與實踐團隊開發的 物件建構與依賴管理框架,Unity 容器即建構於其上。核心特徵:
IBuilderStrategy 組成IBuilderContext 封裝狀態,策略間傳遞資訊IBuilderPolicy 提供策略所需配置資料ILifetimeContainer 統一釋放 IDisposableIReadWriteLocator 用 WeakReference 避免記憶體洩漏| 類型 | 職責 |
|---|---|
BuildPlanStrategy | 建構階段入口,尋找/建立 IBuildPlanPolicy,呼叫 BuildUp |
DynamicMethodConstructorStrategy | 建構動態方法上下文,發射 IL 呼叫構造函數 |
DefaultDynamicBuilderMethodCreatorPolicy | 建立動態方法原型:void BuildUp_xxx(IBuilderContext context) |
ConstructorSelectorPolicy | 選擇標記了注入屬性 (如 [InjectionConstructor]) 的構造函數 |
DynamicMethodBuildPlanCreatorPolicy | 組裝策略鏈,生成動態方法委託,產出 IBuildPlanPolicy |

封裝:TypeToBuild、DynamicMethod、ILGenerator、區域變數表。
.method public hidebysig virtual instance void BuildUp_"methodname" (IBuilderContext context) cil managed
{
.maxstack 3
.locals init (
[0] class typeToBuild 'existingObjectLocal'
[1] class [mscorlib]System.String 'currentParameterName'
)
L_0000: ldarg.0 // context
L_0001: callvirt 'Existing' // 取得 context.Existing (可能為 null)
L_0002: cast class typeToBuild
L_0003: stloc.0 // existingObjectLocal = context.Existing as typeToBuild
L_0004: ldloc.0
L_001f: ldnull
L_0005: ceq
L_0006: brfalse existingObjectNotNull // 若已有實例直接跳過建構
L_0007: ldarg.0
L_0008: call 'ThrowForAttemptingToConstructInterface' // 介面不可實例化拋異常
L_0009: BeginExceptionBlock
L_002e: nop
L_002f: ldstr 'parameters[i].Name' // 參數名稱 → currentParameterName
L_0010: stloc.1
L_0012: ldarg.0 // context
L_0013: callvirt 'Policies' // context.Policies
L_0014: ldtoken 'typeof(IDependencyResolverPolicy)'
L_0015: call System.Type.GetTypeFromHandle
L_0016: ldstr 'key with GUID' // 參數對應的 BuildKey
L_0017: callvirt 'IPolicyList.Get' // 取得 IDependencyResolverPolicy
L_0018: cast class 'typeof(IDependencyResolverPolicy)'
L_0019: ldarg.0 // context
L_0020: callvirt 'Resolve' // Resolve 參數值 → 壓入評估堆疊
L_0021: brtrue L_002e // 所有參數解析完畢跳出
L_0022: ldnull
L_0023: stloc.1 // 清空 currentParameterName
L_0024: newobj 'selectedCtor.Constructor' // 呼叫構造函數,實例壓入堆疊
L_0025: stloc.0 // 存入 existingObjectLocal
L_0026: BeginCatchBlock
exceptionOccuredInResolution:
L_0027: ldloc.1
L_0028: ldnull
L_0029: ceq
L_0030: brfalse exceptionOccuredInResolution
L_0031: rethrow // 重拋原始異常
L_0032: ldloc.1 // 參數名稱
L_0033: ldstr 'signatureString' // 簽章資訊
L_0034: ldarg.0
L_0035: call 'throwForResolutionFailed' // 包裝拋出解析失敗異常
L_0036: EndExceptionBlock
existingObjectNotNull:
}

public class ThreadPool
{
private string poolName = string.Empty;
private int maxThread = 10;
public ThreadPool() { Console.WriteLine("Default ctor called..."); }
[InjectionThreadPool] // 自訂標記屬性
public ThreadPool(string name, int num)
{
this.poolName = name;
this.maxThread = num;
OutPut();
}
private void OutPut() { /* 顯示名稱與最大執行緒數 */ }
}
public interface IParameterChooserPolicy : IBuilderPolicy
{
object GetValue();
}
public class ParameterChooserPolicy<TParameterType> : IParameterChooserPolicy
{
public virtual object GetValue()
{
object obj = ConfigurationManager.AppSettings[typeof(TParameterType).ToString()];
return Convert.ChangeType(obj, typeof(TParameterType));
}
}
從 app.config <appSettings> 讀取同名鍵值 (如 "System.String", "System.Int32")。
public class ThreadPoolBuilder<TTypeToBuild> where TTypeToBuild : class
{
private NamedTypeBuildKey key;
private StagedStrategyChain<BuilderStage> strategies = new StagedStrategyChain<BuilderStage>();
private IReadWriteLocator locator;
private ILifetimeContainer lifetime;
public ThreadPoolBuilder()
{
key = new NamedTypeBuildKey(typeof(TTypeToBuild));
strategies.Add(new BuildPlanStrategy(), BuilderStage.PreCreation);
strategies.Add(new ParametersResolveStrategy(), BuilderStage.Creation); // 自訂參數解析
SetInnerStrategies();
}
protected virtual IStagedStrategyChain SetInnerStrategies()
{
var inner = new StagedStrategyChain<BuilderStage>();
inner.Add(new DynamicMethodConstructorStrategy(), BuilderStage.PreCreation);
return inner;
}
public virtual IPolicyList GetPolicies()
{
var policies = new PolicyList();
policies.Set<IBuildPlanCreatorPolicy>(new DynamicMethodBuildPlanCreatorPolicy(SetInnerStrategies()), key);
policies.Set<IDynamicBuilderMethodCreatorPolicy>(new DefaultDynamicBuilderMethodCreatorPolicy(), key);
policies.Set<IConstructorSelectorPolicy>(new ConstructorSelectorPolicy<InjectionThreadPoolAttribute>(), key);
policies.Set<IParameterChooserPolicy>(new ParameterChooserPolicy<string>(), typeof(string));
policies.Set<IParameterChooserPolicy>(new ParameterChooserPolicy<int>(), typeof(int));
return policies;
}
public TTypeToBuild BuildUp()
{
return new Builder().BuildUp<TTypeToBuild>(
locator, lifetime, GetPolicies(), strategies.MakeStrategyChain(), key, null);
}
}
ThreadPool pool = new ThreadPoolBuilder<ThreadPool>().BuildUp();
// 自動讀取 app.config 中的 System.String / System.Int32 作為建構參數
IBuilderContext 保證策略鏈中狀態不串擾,支援巢狀建構IParameterChooserPolicy + 註冊 Policy,零修改核心OB2 的動態方法構造器注入展示了 框架級基礎設施的極致工藝:用策略鏈組織流程、用 Policy 傳遞配置、用 Reflection.Emit 生成高效能 IL、用上下文隔離狀態。理解這套機制,不僅能深度掌握 Unity 容器內核,更能啟發設計自己的高效能物件建構框架。