zoukankan      html  css  js  c++  java
  • 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)

    仅供参考,内容中会引用部分博友的文章。(侵删)
  • 相关阅读:
    线程池的优雅关闭实践
    InheritableThreadLocal原理解析
    线程池踩坑
    两个线程通讯(生产-卖面包问题)
    谈谈redis的热key问题如何解决
    中国软件杯选题A1数据智能分析报告系统
    《程序员的思维修炼》读后感
    《算法导论》读后感
    《重构》读后感
    《代码整洁之道》读后感
  • 原文地址:https://www.cnblogs.com/zeran/p/14567075.html
Copyright © 2011-2022 走看看