AspectCore.Injector 实现autofac的 ResolveKeyed方法

本文介绍如何为AspectCore.Injector的IOC框架添加按Key值解析服务的功能。通过重载IServiceResolver接口的AddType和Resolve方法,并使用ConcurrentDictionary存储Key值与服务类型的映射,实现了按Key获取服务实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

发现AspectCore.Injector的IOC框架写的特别简单,解析服务只有两个方法:Resolve和ResolveMany

有个需求,需要通过Key值来得到某个服务,它是支持不了的,因为注册和解析服务都没有Key值这个参数

为了实现这个功能,对IServiceResolver这个接口的AddType和Resolve的方法进行了重载,添加Key值的参数

大致思想是,用个全局变量存储他Key值的顺序,根据Key值索引得到解析的服务对象,以下是具体代码:

  1     public static class ServiceExtension
  2     {
  3         #region Members
  4         public static ConcurrentDictionary<string, List<string>> Container { get; private set; } = new ConcurrentDictionary<string, List<string>>();
  5         #endregion
  6 
  7         #region Extend Methods
  8         #region AddType
  9         public static IServiceContainer AddType<TService, TImplementation>(this IServiceContainer serviceDefinitions, string key, Lifetime lifetime = Lifetime.Scoped) where TImplementation : TService
 10         {
 11             var result = serviceDefinitions.AddType<TService, TImplementation>(lifetime);
 12             AddContainer<TService>(key);
 13             return result;
 14         }
 15 
 16         public static IServiceContainer AddType<TService>(this IServiceContainer serviceDefinitions, string key, Lifetime lifetime = Lifetime.Scoped)
 17         {
 18             var result = serviceDefinitions.AddType<TService>(lifetime);
 19             AddContainer<TService>(key);
 20             return result;
 21         }
 22 
 23         public static IServiceContainer AddType(this IServiceContainer serviceDefinitions, Type serviceType, Type implementationType, string key, Lifetime lifetime = Lifetime.Scoped)
 24         {
 25             var result = serviceDefinitions.AddType(serviceType, implementationType, lifetime);
 26             AddContainer(key, serviceType);
 27             return result;
 28         }
 29 
 30         public static IServiceContainer AddType(this IServiceContainer serviceDefinitions, Type serviceType, string key, Lifetime lifetime = Lifetime.Scoped)
 31         {
 32             var result = serviceDefinitions.AddType(serviceType, lifetime);
 33             AddContainer(key, serviceType);
 34             return result;
 35         }
 36         #endregion
 37 
 38         #region AddInstance
 39         public static IServiceContainer AddInstance<TService>(this IServiceContainer serviceDefinitions, TService implementation, string key)
 40         {
 41             var result = serviceDefinitions.AddInstance<TService>(implementation);
 42             AddContainer<TService>(key);
 43             return result;
 44         }
 45 
 46         public static IServiceContainer AddInstance(this IServiceContainer serviceDefinitions, Type serviceType, object implementation, string key)
 47         {
 48             var result = serviceDefinitions.AddInstance(serviceType, implementation);
 49             AddContainer(key, serviceType);
 50             return result;
 51         }
 52         #endregion
 53 
 54         #region Resolve
 55         public static T Resolve<T>(this IServiceResolver serviceResolver, string key) where T : class
 56         {
 57             if (key.IsNull())
 58             {
 59                 return serviceResolver.Resolve<T>();
 60             }
 61 
 62             var typeName = typeof(T)?.FullName ?? string.Empty;
 63             if (!Container.ContainsKey(typeName))
 64             {
 65                 return null;
 66             }
 67 
 68             var list = Container[typeName];
 69             var index = list.FindIndex(t => t == key);
 70             if (index < 0)
 71             {
 72                 return null;
 73             }
 74 
 75             if (list.Count() == 1)
 76             {
 77                return serviceResolver.Resolve<T>();
 78             }
 79 
 80             var array = serviceResolver.ResolveMany<T>();
 81             if (index >= array.Count())
 82             {
 83                 return null;
 84             }
 85 
 86             return array.ToArray()[index];
 87         }
 88         #endregion
 89         #endregion
 90 
 91         #region Private Methods
 92         private static void AddContainer(string key, Type type)
 93         {
 94             if (key.IsNull())
 95             {
 96                 return;
 97             }
 98 
 99             var typeName = type?.FullName ?? string.Empty;
100             if (Container.ContainsKey(typeName))
101             {
102                 var list = Container[typeName];
103                 list.Add(key);
104             }
105             else
106             {
107                 var list = new List<string> { key };
108                 Container[typeName] = list;
109             }
110         }
111 
112         private static void AddContainer<TService>(string key)
113         {
114             AddContainer(key, typeof(TService));
115         }
116         #endregion
117     }

 

转载于:https://www.cnblogs.com/jsnaner/p/9877311.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值