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