兩階段設計#
Autofac 採用兩階段設計:先配置,再建構不可變的容器。
// 階段一:配置
var builder = new ContainerBuilder();
builder.RegisterType<ProductService>().As<IProductService>();
// 階段二:建構
IContainer container = builder.Build();一旦呼叫 Build() 產生 IContainer,註冊就不能再修改。這種 Builder Pattern 確保了容器在使用階段的不可變性。

Figure 13.1: Autofac 的使用模式:先配置,再解析元件
註冊方式#
Autofac 的註冊語法與多數容器方向相反——從具體類型出發,映射到抽象介面:
// Autofac:具體類型 → 抽象介面
builder.RegisterType<SqlProductRepository>().As<IProductRepository>();
// 對比多數容器:抽象介面 → 具體類型
container.Register<IProductRepository, SqlProductRepository>();Autofac 的
RegisterType<T>().As<TInterface>()不使用泛型型別約束,因此無法在編譯期檢查T是否真的實作了TInterface。型別不匹配的錯誤只能在執行期被發現。
Lifetime 與 Scope 管理#
Autofac 提供三種 Lifetime 選項,並嚴格要求透過 Lifetime Scope 解析物件:
| Autofac 方法 | 對應模式 | 說明 |
|---|---|---|
InstancePerDependency() | Transient | 每次解析建立新實例(預設值) |
SingleInstance() | Singleton | 整個容器生命週期只有一個實例 |
InstancePerLifetimeScope() | Scoped | 每個 Scope 內共享同一實例 |
using (var scope = container.BeginLifetimeScope())
{
var service = scope.Resolve<IProductService>();
// 使用 service...
}永遠從 Lifetime Scope 解析物件,而非直接從 Root Container。 直接從 Root Container 解析會導致 Scoped 物件無法正確釋放,造成記憶體洩漏。

Figure 13.3: Autofac 的 Lifetime Scope 作為可共享元件的容器
進階註冊 API#
Autofac 提供彈性但較複雜的 API 處理特殊情境:
WithParameter:傳遞原始值#
builder.RegisterType<ConnectionStringProvider>()
.WithParameter("connectionString", "Server=...");Lambda 註冊:完全控制建構邏輯#
builder.Register(c =>
{
var repo = c.Resolve<IProductRepository>();
return new CachingProductService(repo, TimeSpan.FromMinutes(5));
}).As<IProductService>();處理多重實作#
Last Registration Wins#
當同一個介面有多個註冊時,最後一個註冊的實作會被解析為預設值:
builder.RegisterType<SqlRepository>().As<IRepository>();
builder.RegisterType<CachingRepository>().As<IRepository>();
// 解析 IRepository 會得到 CachingRepository集合注入:IEnumerable<T>#
若需要取得某個介面的所有實作,Autofac 自動支援 IEnumerable<T>:
// 自動注入所有 IEventHandler 實作
public class EventDispatcher(IEnumerable<IEventHandler> handlers) { }Decorator 支援#
builder.RegisterType<SqlRepository>().As<IRepository>();
builder.RegisterDecorator<CachingRepository, IRepository>();RegisterDecorator<TDecorator, TService>() 會自動將 CachingRepository 包裹在 SqlRepository 外層。

Figure 13.5: 以 Transaction、Auditing 和 Security 等 Aspect 豐富 Command Service
Composite 支援#
builder.RegisterComposite<CompositeHandler, IEventHandler>();RegisterComposite<TComposite, TService>() 將所有 IEventHandler 實作組合到 CompositeHandler 中。
Autofac 重點回顧
- 兩階段設計:ContainerBuilder(可變)→ IContainer(不可變)
- 註冊方向是「具體類型 → 抽象介面」,與多數容器相反
- 無泛型型別約束,型別錯誤在執行期才會發現
- 永遠從 Lifetime Scope 解析,不要直接用 Root Container
- 內建 Decorator 和 Composite 支援