惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

W
WeLiveSecurity
The Last Watchdog
The Last Watchdog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
G
Google Developers Blog
博客园 - 叶小钗
雷峰网
雷峰网
人人都是产品经理
人人都是产品经理
博客园_首页
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 三生石上(FineUI控件)
Help Net Security
Help Net Security
Cloudbric
Cloudbric
AI
AI
N
News | PayPal Newsroom
博客园 - 聂微东
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 【当耐特】
Forbes - Security
Forbes - Security
美团技术团队
Stack Overflow Blog
Stack Overflow Blog
SecWiki News
SecWiki News
H
Heimdal Security Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
MyScale Blog
MyScale Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
S
Security @ Cisco Blogs
Google DeepMind News
Google DeepMind News
V
V2EX
大猫的无限游戏
大猫的无限游戏
阮一峰的网络日志
阮一峰的网络日志
S
Security Affairs
L
LangChain Blog
The Hacker News
The Hacker News
F
Full Disclosure
aimingoo的专栏
aimingoo的专栏
Hacker News - Newest:
Hacker News - Newest: "LLM"
腾讯CDC
Webroot Blog
Webroot Blog
A
About on SuperTechFans
H
Hacker News: Front Page
Cyberwarzone
Cyberwarzone
WordPress大学
WordPress大学
L
LINUX DO - 热门话题
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Attack and Defense Labs
Attack and Defense Labs
M
MIT News - Artificial intelligence

博客园 - 大西瓜3721

SVN分支/合并原理及最佳实践 Web.Config中Runtime节点-DLL版本冲突问题 工作问题 Vue资料 轻松实现WCF服务的构造函数依赖注入 WCF 依赖注入-- Attribute MVC视图分析 C#简单枚举和标志枚举的用法和区别 XDate Admin.NET框架资料 日志管理之log4net+Autofac 关于NopCommerce3.6版用户登录详解 NOP源码分析 六 NOP源码分析五---set的存储 NOP源码分析四 Nop源码分析三 NOP源码分析 二 NOP源码分析 一 NopCommerce的资料 IServiceCollection和IServiceProvider 控制反转——Autofac框架 精选10款C#/.NET开发必备类库 11个免费开源后台管理系统模板 H5连接蓝牙打印机打印小票 自定义控件 - 流式布局:TagFlowLayout MVC开源CMS nginx的安装&一个最简单的配置(windows和Centos) DNS解析
AutoFac注册的动态实例 Named和Keyed
大西瓜3721 · 2026-03-16 · via 博客园 - 大西瓜3721

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

复制代码

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);
  }
}

控制器代码:Adminusercontroller

复制代码

 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()
);

}
}

批量注册

复制代码

 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)