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 }

AspectCore和MSDI 实现Name注册以及解析对象的更多相关文章

  1. .NET 用 Unity 依赖注入——概述注册和解析类型(1)

    本文内容 Unity 概述 环境 一个真实的例子 类型注册(Type Registrations) 解析类型(Resolving Types) 跳槽,新公司使用了 Unity,初步看了一下,公司的使用 ...

  2. django实现密码加密的注册(数据对象插入)

    在 django实现密码非加密的注册(数据对象插入)的基础上,我们对视图和注册页面进行了简单修改 视图 from django.shortcuts import render,redirect,ren ...

  3. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  4. 阿里dubbo服务注册原理解析

           阿里分布式服务框架 dubbo现在已成为了外面很多中小型甚至一些大型互联网公司作为服务治理的一个首选或者考虑方案,相信大家在日常工作中或多或少都已经用过或者接触过dubbo了.但是我搜了 ...

  5. oracle 监听静态注册举例解析

    网上有很多关于oracle 监听静态注册的文章,但大多都是简单说说,并没有详细的例子,这里,将结合linux as3 下的oracle 10gR2.0.1 举一个具体的例子 1.在 $ORACLE_H ...

  6. 【转】oracle 监听静态注册举例解析

    网上有很多关于oracle 监听静态注册的文章,但大多都是简单说说,并没有详细的例子,这里,将结合linux as3 下的oracle 10gR2.0.1 举一个具体的例子 1.在 $ORACLE_H ...

  7. windows注册表解析说明

    https://www.cnblogs.com/wfq9330/p/9176654.html

  8. Android数据格式解析对象JSON用法(转)

    地址:http://www.cnblogs.com/devinzhang/archive/2012/01/09/2317315.html 里面的重点: JSON解析案例     (1)解析Object ...

  9. 适用于Firemonkey的Json解析对象XsuperObject使用方法介绍

    XSuperObject是适用于FileMonkey平台的JSON解析组件,能够在Android,IOS,MACOS,WINDOWS等多个平台使用 点击下载 Sample JSON { "n ...

  10. FastJson解析对象及对象数组--项目经验

    第一次使用json,解析工具为FastJson,使用语言为java 常见的json解析实例,以map为例: Map<String,String> map=new HashMap<St ...

随机推荐

  1. 复制文件到U盘提示“一个意外错误使您无法复制该文件”处理办法

    运行cmd 运行 chkdsk H(U盘所在盘符):/f    即可

  2. [Leetcode 108]有序数组转BST二叉搜索树Convert Sorted Array to Binary Search Tree

    题目 https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/ Given an integer array  ...

  3. [Leetcode 559]N叉树的最大深度Maximum Depth of N-ary Tree DFS/BFS模板

    题目 https://leetcode.com/problems/maximum-depth-of-n-ary-tree/ N叉树的最大深度 Given a n-ary tree, find its ...

  4. SqlServer 不能收缩 ID 为 %s 的数据库中 ID 为 %s 的文件,因为它正由其他进程收缩或为空。

    SQLServer数据库通常都不建议进行SHRINKFILE操作,因为SHRINKFILE不当会造成一定的性能问题. 但是当进行了某些操作(例如某个超大的日志类型表转成分区表切换了数据文件),数据库某 ...

  5. VMware linux 网络设置

    控制面板\所有控制面板项\网络连接 1.选择 VMware Virtual Ethernet Adapter for VMnet8 网卡  ->属性-->网络 2.勾选 -> VMw ...

  6. Servlet's characters of get and post

    Tomcat默认是使用ISO8859-1来解码的,ISO8859-1是不支持中文的. 1.post请求解决乱码原因: 服务器不知道按哪种编码来处理HTML等文件来响应给浏览器的,所以处理post请求时 ...

  7. 解决Vue打包后背景图片路径错误问题(转)

    1.原因解析 当用vue-cli自动构建项目后,有两种运行方法,分别是: npm run dev : 提供一个开发的环境,自动热更新,资源使用绝对路径,所以可以正常看到背景图片. npm run bu ...

  8. 复制文本到粘贴板 (vue3)(兼容ios)

    // 点击复制到剪贴板 const copyToClipboard = (content)=> { if (window.clipboardData) { window.clipboardDat ...

  9. jwt auth0 和 jsonwebtoken比较

    参考: https://blog.csdn.net/lizz861109/article/details/104614942/

  10. Neo4j学习(3)--JavaAPI

    Neo4j Java操作 1. Neo4j Java Driver方式操作 使用该方式对数据进行操作时,必须先将Neo4j的服务启动起来. 从官方下载neo4j的Java驱动:https://neo4 ...