.net依赖注入框架 Autofac和MEF的对比

发布于:2025-08-03 ⋅ 阅读:(26) ⋅ 点赞:(0)

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. 代码示例对比

假设有一个模块包含ViewViewModel

// 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结合使用。


网站公告

今日签到

点亮在社区的每一天
去签到