首页/新闻资讯/正文详情

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

发布时间:2026/11/15 18:59:19 来源:云帆数科 栏目:资讯中心
# Autofac 完整详解 + 全部注册方式实战案例
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自动匹配依赖

相关推荐

AI智能体安全审计:Learn-Agentic-AI应用扫描与代码审计系统解析
AI智能体安全审计:Learn-Agentic-AI应用扫描与代码审计系统解析

1. 项目概述:当AI智能体成为安全审计师最近在跟几个做DevSecOps和AI应用开发的朋友聊天,大家不约而同地提到了同一个痛点:随着大模型和智能体(Agent)技术的爆发式应用,我们开发的系统越来越“聪明”&#x… · 2026/10/27 13:55:39

HarmonyOS7 个人信息编辑页:预填数据与头像展示的表单设计
HarmonyOS7 个人信息编辑页:预填数据与头像展示的表单设计

文章目录前言应用场景设计思路实现过程预填数据的状态管理头像区域带预填值的输入框保存按钮完整代码效果调优检测是否有修改离开页面的确认写在最后前言 个人信息编辑页跟注册表单最大的区别是什么?预填数据。用户打开这个页面时,输入框里已经有内容了… · 2026/10/27 12:28:37

如何安全修改暗黑破坏神II存档:终极角色编辑器使用指南
如何安全修改暗黑破坏神II存档:终极角色编辑器使用指南

如何安全修改暗黑破坏神II存档:终极角色编辑器使用指南 【免费下载链接】diablo_edit Diablo II Character editor. 项目地址: https://gitcode.com/gh_mirrors/di/diablo_edit 你是否厌倦了在暗黑破坏神II中重复刷怪只为获得一件心仪的装备?或者… · 2026/11/6 10:48:40

多少v以上需要电工证电子证书查询
多少v以上需要电工证电子证书查询

380V以上必须电工证!考前押题助你稳过考试别被中介坑 不知道去哪报名怕被中介坑,考前押题又难找?特种作业电工证是进入电力行业必须的第一道门槛,但很多人不知道,380V以上的电气设备操作 必须持证上岗… · 2026/11/15 18:58:47

日本电工证好考吗?低学历也能考的良心建议
日本电工证好考吗?低学历也能考的良心建议

日本电工证好考吗?低学历也能考的良心建议 你是不是也这样,觉得自己学历不高,怕报不上名?别急,今天咱们就聊聊【日本电工证好考吗】这个话题,给你点 良心建议 ,帮你把关到底能不能考、该怎么考,尤其适合刚起步、想转行的新手。… · 2026/11/15 18:58:47

电工证换证材料费用全攻略:证书过期了不知道怎么复审延期?通过率揭秘在这里
电工证换证材料费用全攻略:证书过期了不知道怎么复审延期?通过率揭秘在这里

电工证换证材料费用全攻略:证书过期了不知道怎么复审延期?通过率揭秘在这里 证书过期了不知道怎么复审延期?你是不是也遇到过这种情况,电工证快到期了,准备去换证,却发现材料准备不全、流程不熟、费用也不清楚?别急,今天我就从 电工证换证材料费用… · 2026/11/15 18:58:47

电工证年审与换证期限良心建议:过期了别慌,这样做能救回来
电工证年审与换证期限良心建议:过期了别慌,这样做能救回来

电工证年审与换证期限良心建议:过期了别慌,这样做能救回来 证书过期了不知道怎么复审延期?别急,电工证年审与换证期限这件事,你只要弄清楚几个关键点,就能把局面稳住。尤其是像咱们信阳劳务班组负责人,手里几十号人的证件管理,一个疏忽就可能影响整个… · 2026/11/15 18:58:47

电工证技巧视频多久拿证?别怕考不过白交培训费,这几点搞懂稳过
电工证技巧视频多久拿证?别怕考不过白交培训费,这几点搞懂稳过

电工证技巧视频多久拿证?别怕考不过白交培训费,这几点搞懂稳过 怕考不过白交培训费?你不是一个人。现在市面上的电工证技巧视频五花八门,有些甚至打着“保过班”的旗号,但实际操作中,很多学员还是因为没掌握好答题技巧、时间分配和重点章节而折戟。电工… · 2026/11/15 18:58:47

高危特种作业操作证怎么转回本地?良心建议全在这儿
高危特种作业操作证怎么转回本地?良心建议全在这儿

高危特种作业操作证怎么转回本地?良心建议全在这儿 之前考的证在外省能不能转过来?说实话,这几乎是每个转岗或跨省工作的特种作业人员最关心的问题。特别是像信阳这样的地方,很多从业者从外省转回来,手里拿着的高危特种作业操作证却成了“摆设”,因为不… · 2026/11/15 18:57:46

长春初级电工证怎么考?通过率揭秘全在这里
长春初级电工证怎么考?通过率揭秘全在这里

长春初级电工证怎么考?通过率揭秘全在这里 之前考的证在外省能不能转过来?这几乎是每个想从事电工工作的人都会问的问题。特别是那些在外地打拼多年、手里握着一张“外地电工证”的人,到了长春想继续干这一行,第一反应就是“我的证能用吗?”。今天我们就… · 2026/11/15 0:00:50

国内电工证报考条件与考试时间
国内电工证报考条件与考试时间

低压电工证怎么考?学历不高也能报名,官方报名入口全在这 你是不是经常听说“电工证是入行门槛”,但又担心自己学历不够、经验不足,根本报不了名?别急,今天就带你从零了解【国内电工证】的报考流程、考试内容,还有怎么在 官方报名入口… · 2026/11/15 0:00:50

电工作业时如何断电?电子证书到底能不能全国通用?
电工作业时如何断电?电子证书到底能不能全国通用?

电工作业时如何断电?电子证书到底能不能全国通用? 实操考试心里没底怕挂科,特别是电工作业时如何断电这一操作,不仅关系到你能不能拿到证书,更关系到以后能不能顺利上岗。很多人觉得这不过就是“断个电”,但其实这里面的门道可不少,稍有不慎就可能出错… · 2026/11/15 0:00:50

长春初级电工证怎么考?通过率揭秘全在这里
长春初级电工证怎么考?通过率揭秘全在这里

长春初级电工证怎么考?通过率揭秘全在这里 之前考的证在外省能不能转过来?这几乎是每个想从事电工工作的人都会问的问题。特别是那些在外地打拼多年、手里握着一张“外地电工证”的人,到了长春想继续干这一行,第一反应就是“我的证能用吗?”。今天我们就… · 2026/11/15 0:00:50

国内电工证报考条件与考试时间
国内电工证报考条件与考试时间

低压电工证怎么考?学历不高也能报名,官方报名入口全在这 你是不是经常听说“电工证是入行门槛”,但又担心自己学历不够、经验不足,根本报不了名?别急,今天就带你从零了解【国内电工证】的报考流程、考试内容,还有怎么在 官方报名入口… · 2026/11/15 0:00:50

电工作业时如何断电?电子证书到底能不能全国通用?
电工作业时如何断电?电子证书到底能不能全国通用?

电工作业时如何断电?电子证书到底能不能全国通用? 实操考试心里没底怕挂科,特别是电工作业时如何断电这一操作,不仅关系到你能不能拿到证书,更关系到以后能不能顺利上岗。很多人觉得这不过就是“断个电”,但其实这里面的门道可不少,稍有不慎就可能出错… · 2026/11/15 0:00:50

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/15 1:51:20

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/15 4:02:19

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/15 3:02:05

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码