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)

仅供参考,内容中会引用部分博友的文章。(侵删)

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注