# Autofac 完整详解 + 全部注册方式实战案例

Autofac 完整详解 + 全部注册方式实战案例

一、Autofac 核心概述

1. 什么是 Autofac

Autofac 是 .NET 生态最灵活、功能最全的依赖注入DI容器,支持 .NET Framework / .NET Core / .NET 5~8,完美适配控制台、WPF、ASP.NET Core、WinForms。
核心优势:

  1. 灵活的生命周期管理(瞬时、单例、作用域、线程作用域等)
  2. 批量注册、程序集扫描、泛型自动注入
  3. 属性注入、构造注入、方法注入多模式
  4. 模块拆分注册、条件注册、命名/键服务、延迟加载 Lazy
  5. 与 ASP.NET Core、WPF MVVM、SqlSugar、NLog 无缝集成

2. 基础术语

  • 接口(Service):对外暴露抽象IUserService
  • 实现(Implementation):具体类UserService
  • 容器容器(ContainerBuilder):注册所有类型的构建器
  • IContainer:构建完成的根容器,全局唯一
  • ILifetimeScope:作用域容器,子容器,释放时自动销毁实例
  • 生命周期:控制对象创建与销毁时机

3. NuGet 安装

<!-- 核心包 --> Install-Package Autofac <!-- ASP.NET Core 适配(web项目专用) --> Install-Package Autofac.Extensions.DependencyInjection

二、完整项目基础示例(统一测试实体)

先定义统一测试接口与实现,所有注册案例复用:

// 业务接口 public interface IUserService { void Show(); } // 普通实现类 public class UserService : IUserService { public void Show() { Console.WriteLine("UserService 执行"); } } // 带构造参数依赖 public interface IOrderRepo { } public class OrderRepo : IOrderRepo { } public class OrderService { private readonly IOrderRepo _repo; public string Name { get; set; } // 用于属性注入测试 // 构造依赖 public OrderService(IOrderRepo repo) { _repo = repo; } public void Print() { Console.WriteLine($"OrderService, 属性值:{Name}"); } } // 泛型测试 public interface IRepository<T> { } public class Repository<T> : IRepository<T> { } // 模块拆分专用模块类 public class BusinessModule : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterType<UserService>().As<IUserService>(); } }

三、Autofac 全部注册方式 + 可运行案例

前置统一初始化代码(所有案例共用)

// 1. 创建构建器 var builder = new ContainerBuilder(); // ===== 此处填写下面任意注册代码 ===== // 2. 构建根容器 IContainer container = builder.Build(); // 3. 创建作用域(推荐,避免直接用根容器Resolve) using var scope = container.BeginLifetimeScope(); // 4. 解析服务使用 var user = scope.Resolve<IUserService>(); user.Show();

分类1:基础单类型注册(最常用)

1.1 仅注册自身(不绑定接口)

// 只能 Resolve<UserService>(),不能用 IUserService builder.RegisterType<UserService>(); // 解析 var svc = scope.Resolve<UserService>();

1.2 注册实现并暴露接口(标准写法)

builder.RegisterType<UserService>().As<IUserService>(); // 解析:scope.Resolve<IUserService>()

1.3 一个实现绑定多个接口

public interface IBase { } public class UserService : IUserService, IBase { } builder.RegisterType<UserService>() .As<IUserService>() .As<IBase>();

1.4 AsSelf() 同时暴露自身+接口

builder.RegisterType<UserService>() .As<IUserService>() .AsSelf(); // 两种方式都能解析 scope.Resolve<IUserService>(); scope.Resolve<UserService>();

分类2:实例注册(手动new对象,容器不负责创建)

2.1 RegisterInstance 注册现成对象

适合静态配置、第三方SDK实例、单例固定对象

var userSvc = new UserService(); builder.RegisterInstance(userSvc).As<IUserService>(); // 生命周期强制为单例,容器不会新建

2.2 RegisterInstance + 外部传入配置

var config = new AppConfig { ConnectionString = "test" }; builder.RegisterInstance(config).SingleInstance();

分类3:Lambda工厂注册 Register.Register

3.1 简单Lambda创建实例

手动控制构造逻辑,灵活传参

builder.Register(ctx => { // ctx 是当前作用域,可以解析依赖 var repo = ctx.Resolve<IOrderRepo>(); return new OrderService(repo); }).AsSelf();

3.2 带参数构造、动态赋值

builder.Register(ctx => { var repo = ctx.Resolve<IOrderRepo>(); var orderSvc = new OrderService(repo); orderSvc.Name = "工厂赋值"; return orderSvc; }).AsSelf();

3.3 无依赖简单工厂

builder.Register(_ => new UserService()).As<IUserService>();

分类4:泛型批量注册(仓储层必备)

4.1 开放泛型注册 RegisterGeneric

// 自动适配 IRepository<User> IRepository<Order> builder.RegisterGeneric(typeof(Repository<>)) .As(typeof(IRepository<>)); // 使用 var userRepo = scope.Resolve<IRepository<User>>(); var orderRepo = scope.Resolve<IRepository<Order>>();

分类5:程序集批量扫描注册(大型项目核心)

5.1 扫描当前程序集,接口以I开头、实现同命名

var assembly = Assembly.GetExecutingAssembly(); builder.RegisterAssemblyTypes(assembly) // 筛选:只导出 public 类 .PublicOnly() // 匹配规则:实现 IXXX 的 XXX 类 .Where(t => t.Name.StartsWith("User") || t.Name.EndsWith("Service")) // 自动绑定对应接口 .AsImplementedInterfaces() // 默认瞬时生命周期 .InstancePerDependency();

5.2 多程序集扫描(分层架构:Service、Repository)

var asm1 = Assembly.Load("Project.Service"); var asm2 = Assembly.Load("Project.Repository"); builder.RegisterAssemblyTypes(asm1, asm2) .Where(t => t.Name.EndsWith("Service")) .AsImplementedInterfaces();

5.3 排除特定类型、只注册自身

builder.RegisterAssemblyTypes(assembly) .Except<UserService>() // 排除UserService .AsSelf();

分类6:模块拆分注册 Module(大型项目解耦)

6.1 定义Module(前文 BusinessModule)

public class BusinessModule : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterType<UserService>().As<IUserService>(); builder.RegisterType<OrderRepo>().As<IOrderRepo>(); } }

6.2 加载模块

// 方式1:直接new模块 builder.RegisterModule(new BusinessModule()); // 方式2:按程序集扫描所有Module自动加载 builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());

分类7:属性注入、方法注入、构造参数覆盖

7.1 属性注入 PropertiesAutowired()

自动给类中公共属性注入依赖

builder.RegisterType<OrderService>() .AsSelf() .PropertiesAutowired(); // 自动填充所有可解析属性 // 如果只想注入指定属性 builder.RegisterType<OrderService>() .AsSelf() .WithProperty("Name", "手动赋值");

7.2 构造参数显式赋值 WithParameter

覆盖构造函数参数,固定值/从容器解析

// 固定值参数 builder.RegisterType<OrderService>() .WithParameter("repo", new OrderRepo()) .AsSelf(); // 从容器解析参数 builder.RegisterType<OrderService>() .WithParameter( (pi, ctx) => pi.Name == "repo", (pi, ctx) => ctx.Resolve<IOrderRepo>() );

7.3 方法注入 OnActivated / OnActivating

实例创建前后回调,做初始化

builder.RegisterType<OrderService>() .AsSelf() .OnActivating(ctx => { // 创建前执行 var svc = ctx.Instance as OrderService; svc.Name = "激活前赋值"; }) .OnActivated(ctx => { // 创建完成后执行初始化方法 var svc = ctx.Instance as OrderService; svc.Print(); });

分类8:命名服务、键服务(同一接口多实现)

8.1 命名服务 Named

// 两个实现 builder.RegisterType<UserService>().Named<IUserService>("admin"); builder.RegisterType<CustomerUserService>().Named<IUserService>("customer"); // 解析指定名称 var adminSvc = scope.ResolveNamed<IUserService>("admin");

8.2 键服务 Keyed(用枚举/常量做Key)

public enum UserType { Admin, Customer } builder.RegisterType<UserService>().Keyed<IUserService>(UserType.Admin); builder.RegisterType<CustomerUserService>().Keyed<IUserService>(UserType.Customer); var cusSvc = scope.ResolveKeyed<IUserService>(UserType.Customer);

8.3 全部解析 ResolveAll

同一接口多个实现全部取出

var allServices = scope.Resolve<IEnumerable<IUserService>>(); foreach (var s in allServices) s.Show();

分类9:延迟加载 Lazy、Func 工厂注入

9.1 Lazy 延迟实例化(使用时才创建)

无需额外注册,直接构造注入Lazy<IUserService>

public class TestApp { private readonly Lazy<IUserService> _lazyUser; public TestApp(Lazy<IUserService> lazyUser) { _lazyUser = lazyUser; } public void Run() { // 第一次访问Value才创建对象 _lazyUser.Value.Show(); } } builder.RegisterType<TestApp>();

9.2 Func 动态多次创建实例

public class TestApp { private readonly Func<IUserService> _userFactory; public TestApp(Func<IUserService> userFactory) { _userFactory = userFactory; } public void MultiCreate() { var u1 = _userFactory(); var u2 = _userFactory(); } }

四、五大生命周期详解(所有生命周期注册写法)

生命周期控制实例复用规则,开发最容易踩坑

生命周期说明适用场景
InstancePerDependency(默认瞬时)每次Resolve新建无状态服务、轻量工具
SingleInstance(全局单例)整个容器唯一配置、日志、连接池
InstancePerLifetimeScope(作用域单例)每个子Scope一个实例数据库上下文、请求级服务
InstancePerMatchingLifetimeScope指定Tag作用域单例WPF多窗口、多租户
InstancePerRequestASP.NET Core请求单例Web项目专用

4.1 瞬时(默认,可省略)

builder.RegisterType<UserService>() .As<IUserService>() .InstancePerDependency();

4.2 全局单例 SingleInstance

builder.RegisterType<UserService>() .As<IUserService>() .SingleInstance();

4.3 作用域单例 InstancePerLifetimeScope

builder.RegisterType<OrderRepo>() .As<IOrderRepo>() .InstancePerLifetimeScope();

4.4 标记作用域单例(多窗口WPF常用)

// 注册带Tag匹配 builder.RegisterType<UserService>() .As<IUserService>() .InstancePerMatchingLifetimeScope("MainWindow"); // 创建带Tag的作用域 using var windowScope = container.BeginLifetimeScope("MainWindow");

4.5 ASP.NET Core 请求级单例

builder.RegisterType<DbContext>() .InstancePerRequest();

五、容器解析 Resolve 全部用法

using var scope = container.BeginLifetimeScope(); // 1. 基础解析 var user = scope.Resolve<IUserService>(); // 2. 安全解析(不存在不抛异常,返回null) if (scope.TryResolve<IUserService>(out var safeUser)) { safeUser.Show(); } // 3. 命名/键解析 var admin = scope.ResolveNamed<IUserService>("admin"); var cus = scope.ResolveKeyed<IUserService>(UserType.Customer); // 4. 批量解析全部实现 var list = scope.Resolve<IEnumerable<IUserService>>(); // 5. 带参数解析(构造动态传参) var order = scope.Resolve<OrderService>(new NamedParameter("repo", new OrderRepo()));

六、ASP.NET Core 集成 Autofac 完整案例

Program.cs

var builder = WebApplication.CreateBuilder(args); // 替换默认DI为Autofac builder.Host.ConfigureContainer<ContainerBuilder>(autofacBuilder => { // 1. 批量扫描Service层 var asm = Assembly.Load("Project.Service"); autofacBuilder.RegisterAssemblyTypes(asm) .AsImplementedInterfaces() .InstancePerLifetimeScope(); // 2. 加载模块 autofacBuilder.RegisterModule(new BusinessModule()); }); var app = builder.Build();

七、WPF 集成 Autofac 通用模板

var containerBuilder = new ContainerBuilder(); // 注册ViewModel、Service containerBuilder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) .Where(t => t.Name.EndsWith("ViewModel")) .AsSelf() .InstancePerLifetimeScope(); IContainer container = containerBuilder.Build(); // 全局作用域 App.Container = container; // 打开窗口时创建子Scope using var scope = container.BeginLifetimeScope(); var mainVm = scope.Resolve<MainViewModel>(); var window = new MainWindow { DataContext = mainVm }; window.Show();

常见踩坑总结

  1. 不要直接使用根容器container.Resolve(),必须BeginLifetimeScope释放资源
  2. 单例不能依赖作用域实例,会造成生命周期泄漏
  3. 批量扫描时注意过滤抽象类、接口本身
  4. 属性注入不会覆盖构造函数赋值,构造优先
  5. InstancePerRequest 仅Web项目生效,控制台/WPF无效
  6. 注册顺序不影响解析,Autofac自动匹配依赖