Autofac 默認需要顯式注冊每個類型,這是它與MEF在模塊化設計上的主要區別。以下是具體對比說明:
1. Autofac 的基本注冊方式
Autofac 必須通過代碼明確注冊每個需要注入的類型(除非使用特殊掃描機制):
var builder = new ContainerBuilder();
// 必須手動注冊每個類型
builder.RegisterType<ServiceA>().As<IService>();
builder.RegisterType<ServiceB>().As<IService>();
builder.RegisterType<ViewModel>().AsSelf();
var container = builder.Build();
2. 與MEF的關鍵差異
特性 | Autofac | MEF |
---|---|---|
注冊方式 | 顯式注冊(代碼定義) | 隱式注冊(通過[Export] 特性標記) |
模塊發現 | 需手動掃描或配置 | 自動掃描程序集發現導出項 |
動態加載 | 需額外處理(如Assembly.Load ) | 原生支持DirectoryCatalog 動態加載 |
松散耦合 | 依賴接口但需注冊 | 僅需約定接口,無需注冊 |
3. Autofac的替代方案(接近MEF的行為)
如果希望在Autofac中實現類似MEF的自動發現,可以通過以下方式:
方案1:程序集掃描(仍需顯式定義規則)
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces();
方案2:配合Microsoft.Composition
(MEF2)
// 需引用System.Composition
var configuration = new ContainerConfiguration().WithAssembly(typeof(ModuleA).Assembly);
var container = configuration.CreateContainer();
4. 何時選擇Autofac?
- 需要精細控制生命周期(如單例/實例作用域)
- 需要更快的解析性能(Autofac的解析通常比MEF快)
- 項目已深度集成其他DI功能(如AOP、屬性注入)
5. 代碼示例對比
假設有一個模塊包含View
和ViewModel
:
// MEF方式(自動發現)
[Export(typeof(IModule))]
public class MyModule {[Export] public ViewModelA { get; set; } // 自動導出
}// Autofac方式(需手動注冊)
builder.RegisterType<MyModule>().As<IModule>();
builder.RegisterType<ViewModelA>().AsSelf(); // 必須顯式注冊
總結來說,如果您追求完全的模塊化和自動發現,MEF更合適;如果需要精細控制和性能優化,Autofac更優。兩者也可以通過System.Composition
(MEF2)與Autofac結合使用。