
Autofac 完整详解 全部注册方式实战案例一、Autofac 核心概述1. 什么是 AutofacAutofac 是 .NET 生态最灵活、功能最全的依赖注入DI容器支持 .NET Framework / .NET Core / .NET 5~8完美适配控制台、WPF、ASP.NET Core、WinForms。核心优势灵活的生命周期管理瞬时、单例、作用域、线程作用域等批量注册、程序集扫描、泛型自动注入属性注入、构造注入、方法注入多模式模块拆分注册、条件注册、命名/键服务、延迟加载 Lazy与 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 IRepositoryT { } public class RepositoryT : IRepositoryT { } // 模块拆分专用模块类 public class BusinessModule : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterTypeUserService().AsIUserService(); } }三、Autofac 全部注册方式 可运行案例前置统一初始化代码所有案例共用// 1. 创建构建器 var builder new ContainerBuilder(); // 此处填写下面任意注册代码 // 2. 构建根容器 IContainer container builder.Build(); // 3. 创建作用域推荐避免直接用根容器Resolve using var scope container.BeginLifetimeScope(); // 4. 解析服务使用 var user scope.ResolveIUserService(); user.Show();分类1基础单类型注册最常用1.1 仅注册自身不绑定接口// 只能 ResolveUserService()不能用 IUserService builder.RegisterTypeUserService(); // 解析 var svc scope.ResolveUserService();1.2 注册实现并暴露接口标准写法builder.RegisterTypeUserService().AsIUserService(); // 解析scope.ResolveIUserService()1.3 一个实现绑定多个接口public interface IBase { } public class UserService : IUserService, IBase { } builder.RegisterTypeUserService() .AsIUserService() .AsIBase();1.4 AsSelf() 同时暴露自身接口builder.RegisterTypeUserService() .AsIUserService() .AsSelf(); // 两种方式都能解析 scope.ResolveIUserService(); scope.ResolveUserService();分类2实例注册手动new对象容器不负责创建2.1 RegisterInstance 注册现成对象适合静态配置、第三方SDK实例、单例固定对象var userSvc new UserService(); builder.RegisterInstance(userSvc).AsIUserService(); // 生命周期强制为单例容器不会新建2.2 RegisterInstance 外部传入配置var config new AppConfig { ConnectionString test }; builder.RegisterInstance(config).SingleInstance();分类3Lambda工厂注册 Register.Register3.1 简单Lambda创建实例手动控制构造逻辑灵活传参builder.Register(ctx { // ctx 是当前作用域可以解析依赖 var repo ctx.ResolveIOrderRepo(); return new OrderService(repo); }).AsSelf();3.2 带参数构造、动态赋值builder.Register(ctx { var repo ctx.ResolveIOrderRepo(); var orderSvc new OrderService(repo); orderSvc.Name 工厂赋值; return orderSvc; }).AsSelf();3.3 无依赖简单工厂builder.Register(_ new UserService()).AsIUserService();分类4泛型批量注册仓储层必备4.1 开放泛型注册 RegisterGeneric// 自动适配 IRepositoryUser IRepositoryOrder builder.RegisterGeneric(typeof(Repository)) .As(typeof(IRepository)); // 使用 var userRepo scope.ResolveIRepositoryUser(); var orderRepo scope.ResolveIRepositoryOrder();分类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、Repositoryvar 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) .ExceptUserService() // 排除UserService .AsSelf();分类6模块拆分注册 Module大型项目解耦6.1 定义Module前文 BusinessModulepublic class BusinessModule : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterTypeUserService().AsIUserService(); builder.RegisterTypeOrderRepo().AsIOrderRepo(); } }6.2 加载模块// 方式1直接new模块 builder.RegisterModule(new BusinessModule()); // 方式2按程序集扫描所有Module自动加载 builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());分类7属性注入、方法注入、构造参数覆盖7.1 属性注入 PropertiesAutowired()自动给类中公共属性注入依赖builder.RegisterTypeOrderService() .AsSelf() .PropertiesAutowired(); // 自动填充所有可解析属性 // 如果只想注入指定属性 builder.RegisterTypeOrderService() .AsSelf() .WithProperty(Name, 手动赋值);7.2 构造参数显式赋值 WithParameter覆盖构造函数参数固定值/从容器解析// 固定值参数 builder.RegisterTypeOrderService() .WithParameter(repo, new OrderRepo()) .AsSelf(); // 从容器解析参数 builder.RegisterTypeOrderService() .WithParameter( (pi, ctx) pi.Name repo, (pi, ctx) ctx.ResolveIOrderRepo() );7.3 方法注入 OnActivated / OnActivating实例创建前后回调做初始化builder.RegisterTypeOrderService() .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.RegisterTypeUserService().NamedIUserService(admin); builder.RegisterTypeCustomerUserService().NamedIUserService(customer); // 解析指定名称 var adminSvc scope.ResolveNamedIUserService(admin);8.2 键服务 Keyed用枚举/常量做Keypublic enum UserType { Admin, Customer } builder.RegisterTypeUserService().KeyedIUserService(UserType.Admin); builder.RegisterTypeCustomerUserService().KeyedIUserService(UserType.Customer); var cusSvc scope.ResolveKeyedIUserService(UserType.Customer);8.3 全部解析 ResolveAll同一接口多个实现全部取出var allServices scope.ResolveIEnumerableIUserService(); foreach (var s in allServices) s.Show();分类9延迟加载 Lazy、Func 工厂注入9.1 Lazy 延迟实例化使用时才创建无需额外注册直接构造注入LazyIUserServicepublic class TestApp { private readonly LazyIUserService _lazyUser; public TestApp(LazyIUserService lazyUser) { _lazyUser lazyUser; } public void Run() { // 第一次访问Value才创建对象 _lazyUser.Value.Show(); } } builder.RegisterTypeTestApp();9.2 Func 动态多次创建实例public class TestApp { private readonly FuncIUserService _userFactory; public TestApp(FuncIUserService 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.RegisterTypeUserService() .AsIUserService() .InstancePerDependency();4.2 全局单例 SingleInstancebuilder.RegisterTypeUserService() .AsIUserService() .SingleInstance();4.3 作用域单例 InstancePerLifetimeScopebuilder.RegisterTypeOrderRepo() .AsIOrderRepo() .InstancePerLifetimeScope();4.4 标记作用域单例多窗口WPF常用// 注册带Tag匹配 builder.RegisterTypeUserService() .AsIUserService() .InstancePerMatchingLifetimeScope(MainWindow); // 创建带Tag的作用域 using var windowScope container.BeginLifetimeScope(MainWindow);4.5 ASP.NET Core 请求级单例builder.RegisterTypeDbContext() .InstancePerRequest();五、容器解析 Resolve 全部用法using var scope container.BeginLifetimeScope(); // 1. 基础解析 var user scope.ResolveIUserService(); // 2. 安全解析不存在不抛异常返回null if (scope.TryResolveIUserService(out var safeUser)) { safeUser.Show(); } // 3. 命名/键解析 var admin scope.ResolveNamedIUserService(admin); var cus scope.ResolveKeyedIUserService(UserType.Customer); // 4. 批量解析全部实现 var list scope.ResolveIEnumerableIUserService(); // 5. 带参数解析构造动态传参 var order scope.ResolveOrderService(new NamedParameter(repo, new OrderRepo()));六、ASP.NET Core 集成 Autofac 完整案例Program.csvar builder WebApplication.CreateBuilder(args); // 替换默认DI为Autofac builder.Host.ConfigureContainerContainerBuilder(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.ResolveMainViewModel(); var window new MainWindow { DataContext mainVm }; window.Show();常见踩坑总结不要直接使用根容器container.Resolve()必须BeginLifetimeScope释放资源单例不能依赖作用域实例会造成生命周期泄漏批量扫描时注意过滤抽象类、接口本身属性注入不会覆盖构造函数赋值构造优先InstancePerRequest 仅Web项目生效控制台/WPF无效注册顺序不影响解析Autofac自动匹配依赖