AspectCore和MSDI 实现Name注册以及解析对象

news/2024/11/7 18:13:16/

AspectCore 在注册服务这块比较简单,默认是无法根据Name去注册和解析对象,这边做一下这块的扩展

大致原理是根据自定义Name去生成对应的动态类型,然后使用委托或者对象的方式,进行注册

tips:由于底层原理的原因,无法支持Type的方式进行注册

定义好动态类型的接口,以及相关实现

复制代码

 1 public interface INamedService : IDisposable2 {3     object Service { get; }4 }5 6 public interface INamedService<out T> : INamedService7     where T : class8 {9     new T Service { get; }
10 }
11 
12 public interface INamedService<out TService, TNamed> : INamedService<TService>
13     where TService : class
14     where TNamed : struct
15 {
16 }
17 
18 internal class NamedService<TService, TNamed> : INamedService<TService, TNamed>
19     where TService : class
20     where TNamed : struct
21 {
22     ~NamedService()
23     {
24         Dispose(false);
25     }
26 
27     public NamedService(TService service)
28     {
29         Service = service;
30     }
31 
32     public TService Service { get; private set; }
33 
34     object INamedService.Service => Service;
35 
36     public void Dispose()
37     {
38         Dispose(true);
39         GC.SuppressFinalize(this);
40     }
41 
42     private void Dispose(bool disposing)
43     {
44         if (!disposing)
45         {
46             return;
47         }
48 
49         if (Service == null)
50         {
51             return;
52         }
53 
54         if (Service is IDisposable disposable)
55         {
56             disposable.Dispose();
57             Service = null;
58         }
59     }
60 }

复制代码

根据自定义Name和ServiceType生成对应的动态类型

复制代码

 1 public static class NamedBuilder2 {3     private const string KeyPrefix = "Ksd.NamedType.";4     private static readonly ModuleBuilder _moduleBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Ksd.DynamicAssembly.NamedType"), AssemblyBuilderAccess.Run).DefineDynamicModule("NamedTypeModule");5     private static readonly ConcurrentDictionary<string, Type> _namedTypes = new(StringComparer.OrdinalIgnoreCase);6 7     private static Type GetNamedType(string name)8     {9         if (name.IsNull())
10         {
11             throw new ArgumentNullException(nameof(name));
12         }
13 
14         name = KeyPrefix + name;
15 
16         return _namedTypes.GetOrAdd(name, k =>
17         {
18             var tb = _moduleBuilder.DefineType(k, TypeAttributes.Public | TypeAttributes.Sealed, typeof(ValueType));
19             var type = tb.CreateTypeInfo().AsType();
20             return type;
21         });
22     }
23 
24     public static Type CreateServiceType(string name, Type serviceType)
25     {
26         var namedType = GetNamedType(name);
27         return typeof(NamedService<,>).MakeGenericType(serviceType, namedType);
28     }
29 
30     public static Type CreateServiceBaseType(string name, Type serviceType)
31     {
32         var namedType = GetNamedType(name);
33         return typeof(INamedService<,>).MakeGenericType(serviceType, namedType);
34     }
35 
36     public static Type GetNameServiceBaseType(Type namedType)
37     {
38         return namedType.GetInterfaces()[0];
39     }
40 }

复制代码

封装根据自定义的Name注册和解析的相关方法

复制代码

  1 public static class NamedServiceExtensions2 {3     #region AddInstance4     public static IServiceContext AddInstance(this IServiceContext services, Type serviceType, object implementationInstance, string name)5     {6         if (name.IsNull())7         {8             return services.AddInstance(serviceType, implementationInstance);9         }10 11         if (services == null)12         {13             throw new ArgumentNullException(nameof(services));14         }15 16         if (serviceType == null)17         {18             throw new ArgumentNullException(nameof(serviceType));19         }20 21         if (implementationInstance == null)22         {23             throw new ArgumentNullException(nameof(implementationInstance));24         }25 26         var namedType = NamedBuilder.CreateServiceType(name, serviceType);27         services.AddInstance(NamedBuilder.GetNameServiceBaseType(namedType), Activator.CreateInstance(namedType, implementationInstance));28         return services;29     }30 31     public static IServiceContext AddInstance<TService>(this IServiceContext services, TService implementationInstance, string name)32     {33         return services.AddInstance(typeof(TService), implementationInstance, name);34     }35     #endregion36 37     #region AddDelegate38     public static IServiceContext AddDelegate(this IServiceContext services, Type serviceType, Func<IServiceResolver, object> implementationDelegate, string name, Lifetime lifetime = Lifetime.Transient)39     {40         if (name.IsNull())41         {42             return services.AddDelegate(serviceType, implementationDelegate, lifetime);43         }44 45         if (services == null)46         {47             throw new ArgumentNullException(nameof(services));48         }49 50         if (serviceType == null)51         {52             throw new ArgumentNullException(nameof(serviceType));53         }54 55         if (implementationDelegate == null)56         {57             throw new ArgumentNullException(nameof(implementationDelegate));58         }59 60         var namedType = NamedBuilder.CreateServiceType(name, serviceType);61         services.AddDelegate(NamedBuilder.GetNameServiceBaseType(namedType), s => Activator.CreateInstance(namedType, implementationDelegate(s)), lifetime);62         return services;63     }64 65     public static IServiceContext AddDelegate<TService>(this IServiceContext services, Func<IServiceResolver, TService> implementationDelegate, string name, Lifetime lifetime = Lifetime.Transient)66         where TService : class67     {68         return services.AddDelegate(typeof(TService), implementationDelegate, name, lifetime);69     }70     #endregion71 72     #region Resolve73     public static T Resolve<T>(this IServiceResolver serviceResolver, string name)74         where T : class75     {76         if (name.IsNull())77         {78             return serviceResolver.Resolve<T>();79         }80 81         var namedType = NamedBuilder.CreateServiceBaseType(name, typeof(T));82         var namedService = serviceResolver.Resolve(namedType) as INamedService<T>;83         return namedService?.Service;84     }85 86     public static object Resolve(this IServiceResolver serviceResolver, Type serviceType, string name)87     {88         if (name.IsNull())89         {90             return serviceResolver.Resolve(serviceType);91         }92 93         var namedType = NamedBuilder.CreateServiceBaseType(name, serviceType);94         var namedService = serviceResolver.Resolve(namedType) as INamedService;95         return namedService?.Service;96     }97 98     public static IEnumerable<T> ResolveMany<T>(this IServiceResolver serviceResolver, string name)99         where T : class
100     {
101         if (name.IsNull())
102         {
103             return serviceResolver.ResolveMany<T>();
104         }
105 
106         var namedType = NamedBuilder.CreateServiceBaseType(name, typeof(T));
107         var namedServices = serviceResolver.ResolveMany(namedType).OfType<INamedService<T>>();
108         return namedServices.Select(t => t.Service);
109     }
110 
111     public static IEnumerable<object> ResolveMany(this IServiceResolver serviceResolver, Type serviceType, string name)
112     {
113         if (name.IsNull())
114         {
115             return serviceResolver.ResolveMany(serviceType);
116         }
117 
118         var namedType = NamedBuilder.CreateServiceBaseType(name, serviceType);
119         var namedServices = serviceResolver.ResolveMany(namedType) as IEnumerable<INamedService>;
120         return namedServices.Select(t => t.Service);
121     }
122     #endregion
123 
124     #region Remove
125     public static IServiceContext RemoveAll(this IServiceContext services, Type serviceType, string name)
126     {
127         if (name.IsNull())
128         {
129             return services.RemoveAll(serviceType);
130         }
131 
132         var namedType = NamedBuilder.CreateServiceBaseType(name, serviceType);
133         services.RemoveAll(namedType);
134         return services;
135     }
136 
137     public static IServiceContext RemoveAll<T>(this IServiceContext services, string name)
138         where T : class
139     {
140         return services.RemoveAll(typeof(T), name);
141     }
142     #endregion
143 
144     #region Other
145     public static bool Contains(this IServiceContext services, Type serviceType, string name)
146     {
147         if (name.IsNull())
148         {
149             return services.Contains(serviceType);
150         }
151 
152         var namedType = NamedBuilder.CreateServiceBaseType(name, serviceType);
153         return services.Contains(namedType);
154     }
155     #endregion
156 }

复制代码

根据以上原理,MSDI亦可作对应的注册以及解析方法

复制代码

  1 public static class NamedServiceExtensions2 {3     #region Add4     public static IServiceCollection AddSingleton(this IServiceCollection services, Type serviceType, object implementationInstance, string name)5     {6         services.AddNamed(serviceType, _ => implementationInstance, name, ServiceLifetime.Singleton);7         return services;8     }9 10     public static IServiceCollection AddSingleton<TService>(this IServiceCollection services, TService implementationInstance, string name)11         where TService : class12     {13         return services.AddSingleton(typeof(TService), implementationInstance, name);14     }15 16     public static IServiceCollection AddSingleton(this IServiceCollection services, Type serviceType, Func<IServiceProvider, object> implementationFactory, string name)17     {18         services.AddNamed(serviceType, implementationFactory, name, ServiceLifetime.Singleton);19         return services;20     }21 22     public static IServiceCollection AddSingleton<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory, string name)23         where TService : class24     {25         return services.AddSingleton(typeof(TService), implementationFactory, name);26     }27 28     public static IServiceCollection AddScoped(this IServiceCollection services, Type serviceType, Func<IServiceProvider, object> implementationFactory, string name)29     {30         services.AddNamed(serviceType, implementationFactory, name, ServiceLifetime.Scoped);31         return services;32     }33 34     public static IServiceCollection AddScoped<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory, string name)35         where TService : class36     {37         return services.AddScoped(typeof(TService), implementationFactory, name);38     }39 40     public static IServiceCollection AddTransient(this IServiceCollection services, Type serviceType, Func<IServiceProvider, object> implementationFactory, string name)41     {42         services.AddNamed(serviceType, implementationFactory, name, ServiceLifetime.Transient);43         return services;44     }45 46     public static IServiceCollection AddTransient<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory, string name)47         where TService : class48     {49         return services.AddTransient(typeof(TService), implementationFactory, name);50     }51 52     public static IServiceCollection AddNamed(this IServiceCollection services, Type serviceType, Func<IServiceProvider, object> implementationFactory, string name, ServiceLifetime lifetime = ServiceLifetime.Transient)53     {54         if (name.IsNull())55         {56             services.Add(ServiceDescriptor.Describe(serviceType, implementationFactory, lifetime));57             return services;58         }59 60         if (services == null)61         {62             throw new ArgumentNullException(nameof(services));63         }64 65         if (serviceType == null)66         {67             throw new ArgumentNullException(nameof(serviceType));68         }69 70         if (implementationFactory == null)71         {72             throw new ArgumentNullException(nameof(implementationFactory));73         }74 75         var namedType = NamedBuilder.CreateServiceType(name, serviceType);76 77         services.Add(ServiceDescriptor.Describe(namedType, s => Activator.CreateInstance(namedType, implementationFactory(s)), lifetime));78         return services;79     }80     #endregion81 82     #region GetService83     public static T GetService<T>(this IServiceProvider serviceProvider, string name)84         where T : class85     {86         if (serviceProvider == null)87         {88             throw new ArgumentNullException(nameof(serviceProvider));89         }90 91         if (name.IsNull())92         {93             return serviceProvider.GetService<T>();94         }95 96         var namedType = NamedBuilder.CreateServiceBaseType(name, typeof(T));97         var namedService = serviceProvider.GetService(namedType) as INamedService<T>;98         return namedService?.Service;99     }
100 
101     public static object GetService(this IServiceProvider serviceProvider, Type serviceType, string name)
102     {
103         if (serviceProvider == null)
104         {
105             throw new ArgumentNullException(nameof(serviceProvider));
106         }
107 
108         if (name.IsNull())
109         {
110             return serviceProvider.GetService(serviceType);
111         }
112 
113         var namedType = NamedBuilder.CreateServiceBaseType(name, serviceType);
114         var namedService = serviceProvider.GetService(namedType) as INamedService;
115         return namedService?.Service;
116     }
117 
118     public static IEnumerable<T> GetServices<T>(this IServiceProvider serviceProvider, string name)
119         where T : class
120     {
121         if (serviceProvider == null)
122         {
123             throw new ArgumentNullException(nameof(serviceProvider));
124         }
125 
126         if (name.IsNull())
127         {
128             return serviceProvider.GetServices<T>();
129         }
130 
131         var namedType = NamedBuilder.CreateServiceBaseType(name, typeof(T));
132         var namedServices = serviceProvider.GetServices(namedType) as IEnumerable<INamedService<T>>;
133         return namedServices.Select(t => t.Service);
134     }
135 
136     public static IEnumerable<object> GetServices(this IServiceProvider serviceProvider, Type serviceType, string name)
137     {
138         if (serviceProvider == null)
139         {
140             throw new ArgumentNullException(nameof(serviceProvider));
141         }
142 
143         if (name.IsNull())
144         {
145             return serviceProvider.GetServices(serviceType);
146         }
147 
148         var namedType = NamedBuilder.CreateServiceBaseType(name, serviceType);
149         var namedServices = serviceProvider.GetServices(namedType) as IEnumerable<INamedService>;
150         return namedServices.Select(t => t.Service);
151     }
152     #endregion
153 
154     #region Remove
155     public static IServiceCollection RemoveAll(this IServiceCollection services, Type serviceType, string name)
156     {
157         var namedType = NamedBuilder.CreateServiceBaseType(name, serviceType);
158         services.RemoveAll(namedType);
159         return services;
160     }
161 
162     public static IServiceCollection RemoveAll<T>(this IServiceCollection services, string name)
163     {
164         return services.RemoveAll(typeof(T), name);
165     }
166     #endregion
167 
168     #region Other
169     public static bool Contains(this IServiceCollection services, Type serviceType, string name)
170     {
171         if (name.IsNull())
172         {
173             return services.Contains(serviceType);
174         }
175 
176         var namedType = NamedBuilder.CreateServiceBaseType(name, serviceType);
177         return services.Contains(namedType);
178     }
179     #endregion
180 }

复制代码

 


http://www.ppmy.cn/news/1027880.html

相关文章

Java程序猿搬砖笔记(十六)

文章目录 狂神说-Elasticsearch 7.6入门学习笔记Windows Elasticsearch IK分词器插件启动报错Elasticsearch的ik分词器自定义字典myDict.dic的编码格式需要为UTF-8,否则无效Elasticsearch使用term查询无数据返回的原因Elasticsearch如果没给映射&#xff0c;字段默认使用standa…

SQL 语句解析过程详解

SQL 语句解析过程详解&#xff1a; 1&#xff0e;输入SQL语句 2&#xff0e;词法分析------flex 使用词法分析器&#xff08;由Flex生成&#xff09;将 SQL 语句分解为一个个单词&#xff0c;这些单词被称为“标记“。标记包括关键字、标识符、运算符、分隔符等。 2.1 flex 原…

vue插槽是什么?如何使用?

1、意义 插槽是vue提供的一个内置组件&#xff0c;是一个占位符。作用是可以向组件中传递一段html代码&#xff0c;加强了组件封装性以及复用性。 2、分类 插槽通常分为匿名插槽、具名插槽、作用域插槽 匿名插槽&#xff1a; 顾名思义就是没有名字的插槽&#xff0c;我们通…

软件测试基础篇——Shell

1、 shell概述 脚本&#xff1a;也是属于文本文件/文本文档&#xff0c;除了读和写之外&#xff0c;还可以直接被执行/运行&#xff0c;一句话总结&#xff1a;一个可以直接被执行(运行)的文件/文档&#xff0c;被称为“脚本” shell脚本&#xff1a;利用shell技术编写出来的一…

【Go 基础篇】Go语言浮点类型:探索浮点数的特点与应用

介绍 浮点数是计算机编程中用于表示实数的一种数据类型&#xff0c;用于处理具有小数部分的数值。Go语言&#xff08;Golang&#xff09;提供了两种主要的浮点数类型&#xff1a;float32和float64&#xff0c;分别用于单精度和双精度浮点数的表示。本篇博客将深入探讨Go语言中…

ol问题总结二

一、加载坐标系是4326格式的&#xff0c;使用wfsServer发布的服务&#xff0c;图层加载失败&#xff1b;坐标系是3857格式的。图层加载正常 原因&#xff1a;4326格式的&#xff0c;发布出来的&#xff0c;经纬度是颠倒的 解决方案一&#xff1a;将经纬度进行反转 <templa…

Ubuntu系统kubeadm安装K8S_v1.25.x容器使用docker(K8S_v1.24版本以后依然使用docker容器管理)

安装所需要的全部文档请点击这里下载 系统是&#xff1a; rootk8s-master:~# cat /etc/lsb-release DISTRIB_IDUbuntu DISTRIB_RELEASE22.04 DISTRIB_CODENAMEjammy DISTRIB_DESCRIPTION“Ubuntu 22.04.3 LTS” rootk8s-master:~# uname -a Linux k8s-master 5.15.0-76-generi…

Spring源码系列:核心概念解析

前言 本文旨在为读者解析Spring源码中的关键类&#xff0c;以便读者在深入阅读源码时&#xff0c;能够了解关键类的作用和用途。在阅读Spring源码时&#xff0c;经常会遇到一些不熟悉的概念&#xff0c;了解关键类的作用可以帮助读者更好地理解这些概念。 BeanDefinition Be…