(资料图)
AspectCore 在注册服务这块比较简单,默认是无法根据Name去注册和解析对象,这边做一下这块的扩展
大致原理是根据自定义Name去生成对应的动态类型,然后使用委托或者对象的方式,进行注册
tips:由于底层原理的原因,无法支持Type的方式进行注册
定义好动态类型的接口,以及相关实现
1 public interface INamedService : IDisposable 2 { 3 object Service { get; } 4 } 5 6 public interface INamedService: INamedService 7 where T : class 8 { 9 new T Service { get; }10 }11 12 public interface INamedService : INamedService 13 where TService : class14 where TNamed : struct15 {16 }17 18 internal class NamedService : INamedService 19 where TService : class20 where TNamed : struct21 {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_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(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 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 (this IServiceContext services, Func 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 (this IServiceResolver serviceResolver, string name) 74 where T : class 75 { 76 if (name.IsNull()) 77 { 78 return serviceResolver.Resolve (); 79 } 80 81 var namedType = NamedBuilder.CreateServiceBaseType(name, typeof(T)); 82 var namedService = serviceResolver.Resolve(namedType) as INamedService ; 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 ResolveMany (this IServiceResolver serviceResolver, string name) 99 where T : class100 {101 if (name.IsNull())102 {103 return serviceResolver.ResolveMany ();104 }105 106 var namedType = NamedBuilder.CreateServiceBaseType(name, typeof(T));107 var namedServices = serviceResolver.ResolveMany(namedType).OfType >();108 return namedServices.Select(t => t.Service);109 }110 111 public static IEnumerable
根据以上原理,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(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 implementationFactory, string name) 17 { 18 services.AddNamed(serviceType, implementationFactory, name, ServiceLifetime.Singleton); 19 return services; 20 } 21 22 public static IServiceCollection AddSingleton (this IServiceCollection services, Func 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 implementationFactory, string name) 29 { 30 services.AddNamed(serviceType, implementationFactory, name, ServiceLifetime.Scoped); 31 return services; 32 } 33 34 public static IServiceCollection AddScoped (this IServiceCollection services, Func 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 implementationFactory, string name) 41 { 42 services.AddNamed(serviceType, implementationFactory, name, ServiceLifetime.Transient); 43 return services; 44 } 45 46 public static IServiceCollection AddTransient (this IServiceCollection services, Func 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 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 (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 (); 94 } 95 96 var namedType = NamedBuilder.CreateServiceBaseType(name, typeof(T)); 97 var namedService = serviceProvider.GetService(namedType) as INamedService ; 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 GetServices (this IServiceProvider serviceProvider, string name)119 where T : class120 {121 if (serviceProvider == null)122 {123 throw new ArgumentNullException(nameof(serviceProvider));124 }125 126 if (name.IsNull())127 {128 return serviceProvider.GetServices ();129 }130 131 var namedType = NamedBuilder.CreateServiceBaseType(name, typeof(T));132 var namedServices = serviceProvider.GetServices(namedType) as IEnumerable >;133 return namedServices.Select(t => t.Service);134 }135 136 public static IEnumerable
关键词: