• 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
    13     where TService : class
    14     where TNamed : struct
    15 {
    16 }
    17 
    18 internal class NamedService : INamedService
    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()[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, Funcobject> 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 : class
    100     {
    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<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;
    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(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(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, Funcobject> 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, Funcobject> 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, Funcobject> 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, Funcobject> 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 : class
    120     {
    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<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;
    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(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 }
    复制代码

     

  • 相关阅读:
    论文速览 | TRS 2023: 使用合成微多普勒频谱进行城市鸟类和无人机分类
    光伏仪器-87110A/B太阳辐照度计
    Lua中文语言编程源码-第十节,更改ltm.c 元格操作函数, 使Lua加载中文库关键词(执行诸如__索引,__新索引,__加等元表操作)
    数据结构:二叉树(超详解析)
    信息学奥赛一本通:1127:图像旋转
    JavaScript基础(详细总结)
    本地缓存方法
    ubuntu安装 notepad
    【23种设计模式】中介者模式(Mediator Pattern) .Net Core实现
    CSS实现文字闪动效果
  • 原文地址:https://www.cnblogs.com/jsnaner/p/17347050.html