奔跑的小猪仔 发表于 2023-4-23 18:56:41

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

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();
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 } 

来源:https://www.cnblogs.com/jsnaner/archive/2023/04/23/17347050.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: AspectCore和MSDI 实现Name注册以及解析对象