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

news2024/12/28 11:11:47

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

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

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

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

复制代码

 1 public interface INamedService : IDisposable
 2 {
 3     object Service { get; }
 4 }
 5 
 6 public interface INamedService<out T> : INamedService
 7     where T : class
 8 {
 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 NamedBuilder
 2 {
 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 NamedServiceExtensions
  2 {
  3     #region AddInstance
  4     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     #endregion
 36 
 37     #region AddDelegate
 38     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 : class
 67     {
 68         return services.AddDelegate(typeof(TService), implementationDelegate, name, lifetime);
 69     }
 70     #endregion
 71 
 72     #region Resolve
 73     public static T Resolve<T>(this IServiceResolver serviceResolver, string name)
 74         where T : class
 75     {
 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 NamedServiceExtensions
  2 {
  3     #region Add
  4     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 : class
 12     {
 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 : class
 24     {
 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 : class
 36     {
 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 : class
 48     {
 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     #endregion
 81 
 82     #region GetService
 83     public static T GetService<T>(this IServiceProvider serviceProvider, string name)
 84         where T : class
 85     {
 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.coloradmin.cn/o/871582.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaWeb 速通JSP

目录 一、JSP快速入门 1.基本介绍 : 2.运行原理 : 二、JSP语法 1.page指令 : 2.声明脚本 : 3.表达式脚本 : 4.Java代码脚本 : 5.JSP注释 : 三、JSP对象 1.九大内置对象 : 2.四大域对象 : 1 基本介绍 2 应用实例 3.关于请求转发标签 : 一、JSP快速入门 1.基本介绍 …

用友-NC-Cloud远程代码执行漏洞[2023-HW]

用友-NC-Cloud远程代码执行漏洞[2023-HW] 一、漏洞介绍二、资产搜索三、漏洞复现PoC小龙POC检测脚本: 四、修复建议 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#…

KafkaStream:Springboot中集成

1、在kafka-demo中创建配置类 配置kafka参数 package com.heima.kafkademo.config;import lombok.Data; import org.apache.kafka.common.serialization.Serdes; import org.apache.kafka.streams.StreamsConfig; import org.springframework.boot.context.properties.Configu…

基于grpc从零开始搭建一个准生产分布式应用(2) - 工程构建

开始本章之前默认读者已经配置好了以下环境&#xff1a;Intellij IDEA 2022.1.2、JDK 1.8.0_144、Maven 3&#xff0c;另外也建议大家在一些免费代码托管平台开个帐号&#xff0c;这样就可以免费使用git做版本处理了&#xff0c;笔者自己私人使用的是阿里云的云效平台。因为此专…

【Lua基础入门】解密世界上最快的脚本语言

文章目录 前言一、Lua简介二、Lua功能三、安装LuaUbuntu LinuxWindows安装Lua 四、第一个Lua程序总结 前言 Lua是一种轻量级、快速且可嵌入的脚本语言&#xff0c;广泛应用于游戏开发、嵌入式系统、脚本扩展等领域。它的设计目标是简单、高效、可定制和易于集成。本文将介绍Lu…

射频入门知识-1

信号源 示波器 综合测试仪 功率计 噪声测试仪 频谱分析仪 频谱分析仪: 放大器的噪声系数测试 放大器增益测试 噪声和增益是放大器的最关键指标&#xff0c;学学怎么用频谱仪做放大器的噪声测试 那个 hbf740 输入和输出阻抗匹配具体怎么搞 《ADS2011射频电路设计与…

iOS Epub阅读器改造记录

六个月前在这个YHEpubDemo阅读器的基础上做了一些优化&#xff0c;这里做一下记录。 1.首行缩进修复 由于分页的存在&#xff0c;新的一页的首行可能是新的一行&#xff0c;则应该缩进&#xff1b;也可能是前面一页段落的延续&#xff0c;这时候不应该缩进。YHEpubDemo基于XDS…

Cenos7 搭建Minio集群部署服务器(一)

------> 道 | 法 | 术 | 器 | 势 <------ 多台服务器间免密登录|免密拷贝 Cenos7 搭建Minio集群部署服务器(一) 企业级开源对象存储(看看官网吹的牛B) 开源为云提供动力。开源为企业提供动力。开源为 MinIO 提供支持。每天都有成千上万的客户和社区成员信任 Mi…

Spring Boot @Validated 验证注解的使用

1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId> </dependency> 2、使用 2.1、非对象参数 参数如果是非对象格式&#xff0c;需要在controller类上面添…

cf暑假训练 1700-1800 day1

cf暑假训练 1700-1800 day1 1852B Imbalanced Arrays1850H. The Third Letter1833G Ksyusha and Chinchilla1833F Ira and Flamenco&#xff08;补完线段树来看&#xff09;1809D Binary String Sorting1780D Bit Guessing Game&#xff08;这题真的好难&#xff0c;我只能说我…

yolov5、YOLOv7、YOLOv8改进:注意力机制CA

论文题目&#xff1a;《Coordinate Attention for Efficient Mobile NetWork Design》论文地址&#xff1a; https://arxiv.org/pdf/2103.02907.pdf 本文中&#xff0c;作者通过将位置信息嵌入到通道注意力中提出了一种新颖的移动网络注意力机制&#xff0c;将其称为“Coordin…

msvcp120.dll丢失的解决方法?分享三种常见解决方法

msvcp120.dll是一个动态链接库文件&#xff0c;它是Microsoft Visual C Redistributable包中的一个组成部分。它是用于支持C编程语言的运行时库文件之一。它包含了许多标准库函数、容器类、算法和其他与C语言相关的功能。这些功能包括内存管理、字符串处理、数学计算、文件操作…

每日一题 206反转链表

题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]示例 3&#xff1a; …

浅谈XML配置实现逻辑

XML简介 什么是XML&#xff1f; xml是可扩展的标记语言 XML的作用 主要作用&#xff1a; 1.用来保存数据&#xff0c;而且这些数据具有自我描述性 2.他可以作为项目或者模块的配置文件 3.还可以作为网络传输数据的格式&#xff08;现在JSON为主&#xff09; 第一个实例 命…

计算机组成原理-笔记-汇总

&#x1f4da; 前言 本人在备考408&#xff0c;王道讲得的确不错&#xff0c;本人之前也看过哈工大【刘宏伟老师】的课&#xff0c;两者对比下来。 王道——更加基础&#xff0c;对小白更加友好哈工大——偏实践偏硬件&#xff08;会将更多的代码硬件设计&#xff09; PS&#…

SpringBoot2-Tomcat部署

1.排除内置 Tomcat 在pom.xml文件中的下添加以下代码&#xff0c;用于排除SpringBoot内置Tomcat <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion&…

什么是CSS中的渐变(gradient)?如何使用CSS创建线性渐变和径向渐变?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 渐变&#xff08;Gradient&#xff09;在CSS中的应用⭐ 线性渐变&#xff08;Linear Gradient&#xff09;语法&#xff1a;示例&#xff1a; ⭐ 径向渐变&#xff08;Radial Gradient&#xff09;语法&#xff1a;示例&#xff1a; ⭐ 写…

Kotlin和Java互操作时的可空性

注&#xff1a;文中demo的kt版本是1.7.10 一、kotlin语言中的可空性设计 在Java语言中的NPE&#xff08;NullPointerException&#xff09;可以说非常常见&#xff0c;而且诟病已久。 kotlin做为后起之秀&#xff0c;在空指针的问题上进行了升级&#xff0c;即&#xff1…

day9 10-牛客67道剑指offer-JZ66、19、20、75、23、76、8、28、77、78

文章目录 1. JZ66 构建乘积数组暴力解法双向遍历 2. JZ19 正则表达式匹配3. JZ20 表示数值的字符串有限状态机遍历 4. JZ75 字符流中第一个不重复的字符5. JZ23 链表中环的入口结点快慢指针哈希表 6. JZ76 删除链表中重复的结点快慢指针三指针如果只保留一个重复结点 7. JZ8 二…

HttpRunner自动化工具之设置代理和请求证书验证

httprunner设置代理&#xff1a; httprunner 库本身没有提供设置代理的接口&#xff0c;但是底层使用了urllib.requests 等库&#xff0c;可以设置HTTP_PROXY 和HTTPS_PROXY 环境变量&#xff0c;常用的网络库会自动识别这些环境变量。 日常调试使用代理&#xff08;如charles…