AutoFac注册的动态实例 Named和Keyed
named和keyed是有多个实现时,应用程序根据不同参数或不同场景下进行选择性实例。(我理解是这样的,能想到的场景:支付(根据用户选择实例 支付宝或微信))

using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using AdminWebApi.IServices; using AdminWebApi.Service; using Autofac; namespace AdminWebApi.Autofac { public class AutofacMoule : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly())//注册整个程序集 .Where(n => n.Name.EndsWith("Service")).AsImplementedInterfaces()//注册程序集内以Service结尾的文件 .SingleInstance();//单例模式 //.InstancePerLifetimeScope(); builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()) .Where(n => n.Name.EndsWith("Repository")).AsImplementedInterfaces()//注册程序集内以Repository结尾的文件 .SingleInstance(); builder.RegisterType<twoUserService>().As<IUserService>().SingleInstance(); builder.RegisterType<twoUserService>().Named<IUserService>("two").As<IUserService>().InstancePerDependency(); builder.RegisterType<UserService>().Named<IUserService>("one").As<IUserService>().InstancePerDependency(); builder.RegisterType<UserService>().Keyed<IUserService>(keyid.one).As<IUserService>().InstancePerDependency(); builder.RegisterType<twoUserService>().Keyed<IUserService>(keyid.two).As<IUserService>().InstancePerDependency(); } } public enum keyid { one = 1, two = 2 } }
这里是注册代码的截图与AutofacModule代码,用不同颜色框标识了named 和keyed。(黄色是固定注册;蓝色是同时注册了两个不同的实现,用named区分;褐色是同时注册了两个不同的实现,用keyed区分)

public class AdminUserController : ControllerBase { public IUserService _userservice; private readonly IMapper _mapper; private readonly IComponentContext componentContext; public AdminUserController(IUserService userService,IMapper mapper,IComponentContext componentContext) { _userservice = userService; this._mapper = mapper; this.componentContext = componentContext; } [HttpGet("getuserByid")] public async Task<UsersDto> GetDtoAsync(int uid,int utype,int ukeyid) { switch (utype) { case 1: _userservice = componentContext.ResolveNamed<IUserService>("one"); break; case 2: _userservice = componentContext.ResolveNamed<IUserService>("two");break; default: break ; } switch (ukeyid) { case 1: _userservice = componentContext.ResolveKeyed<IUserService>(keyid.one); break; case 2: _userservice = componentContext.ResolveKeyed<IUserService>(keyid.two); break; } //var two = container.ResolveNamed<IUserService>("two"); //builder.Build().ResolveNamed<IUserService>("two"); return await _userservice.GetUsers(uid); } }
黄色选中是固定注册,在构造函数中直接注入使用就可以。
蓝色和褐色选中的为 named和keyed,都需要使用到 autofac的IComponentContext 上下文对象,通过构造注入即可.
根据传来的不同参数确定使用哪个实例。
官方解释:https://autofaccn.readthedocs.io/zh/latest/advanced/keyed-services.html?highlight=named
我个人认为named更方便些可以使用 实现的类名当做named :
builder.RegisterType<twoUserService>().Named<IUserService>(nameof(twoUserService)).As<IUserService>().InstancePerDependency();
(注:以上 AutofacModule中使用named注册的时候是一个一个注册的, 可以使用批量注册,以下是批量注册和使用,不清楚这种方式是不是更好一些。)
#region 批量注册

public class AutofacMoule : Module { protected override void Load(ContainerBuilder builder) { typeof(IUserService).Assembly.GetTypes() .Where(t => t.GetInterfaces().Contains(typeof(IUserService))).ToList() .ForEach(w => builder.RegisterType(w).Named<IUserService>(w.Name).As<IUserService>().InstancePerDependency() ); } }
#endregion 批量注册结束
演示结果:userService 在名字前加了一个字符串“7788”
twoUserService取出数据没做操作
keyid=1 实例的是userService 输出名字“7788Duh”;
kid=2实例的是twouserService 输出名字“DuhDuh”;
( 注:name:duhduh 两遍是用automapper做的两个字段映射,不用在意。)
AutoFac生命周期 https://autofaccn.readthedocs.io/zh/latest/lifetime/instance-scope.html
每个依赖一个实例(Instance Per Dependency)
单一实例(Single Instance)
每个生命周期作用域一个实例(Instance Per Lifetime Scope)
每个匹配的生命周期作用域一个实例(Instance Per Matching Lifetime Scope)
每个请求一个实例(Instance Per Request)
每次被拥有一个实例(Instance Per Owned)
线程作用域(Thread Scope)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)