大致原理是根据自定义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 }