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

这里是注册代码的截图与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

 黄色选中是固定注册,在构造函数中直接注入使用就可以。

蓝色和褐色选中的为 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)

仅供参考,内容中会引用部分博友的文章。(侵删)
原文地址:https://www.cnblogs.com/zeran/p/14567075.html