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

科技资讯 投稿 6600 0 评论

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

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

 

编程笔记 » AspectCore和MSDI 实现Name注册以及解析对象

赞同 (29) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽