您的位置: 首页 > 知识 > 正文

今日看点:AspectCore和MSDI 实现Name注册以及解析对象

2023-04-23 21:05:58 来源:博客园


(资料图)

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 : INamedService13     where TService : class14     where TNamed : struct15 {16 }17 18 internal class NamedService : INamedService19     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 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     #endregion123 124     #region Remove125     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 : class139     {140         return services.RemoveAll(typeof(T), name);141     }142     #endregion143 144     #region Other145     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     #endregion156 }

根据以上原理,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 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     #endregion153 154     #region Remove155     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     #endregion167 168     #region Other169     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     #endregion180 }                                
							 

关键词:

湖南省人社厅公布7个热门职业的专项职业能力考核规范
怎样开展直播、进行直播复盘?母婴护理需要掌握哪些技巧……近日,湖南省人社厅公布电商直播销售、母婴护理等7个热门职业的专项职业能力考核
2022-06-20
唐山曹妃甸推动京津冀协同发展 产业协同转移全面提速
春暖渤海湾,书写新画卷。位于唐山曹妃甸的金隅天坛(唐山)木业科技有限公司的生产车间内一片繁忙景象——铺装、压机、翻板等工作正紧张有序
2022-03-19
石家庄海关共签发RCEP原产地证书864份 货值3.9亿元
自今年1月1日RCEP(《区域全面经济伙伴关系协定》)正式实施以来,截至3月14日,石家庄海关共签发RCEP原产地证书864份,货值3 9亿元。据介绍
2022-03-19
蚌埠海关累计签发RCEP原产地证书35份 涉及金额2583.09万元
在蚌埠海关报关大厅原产地证办理窗口,海关关员仔细核对着递交过来的材料。十分钟后,一份RCEP原产地证书打印盖章后交到了企业业务员手中。
2022-03-19
昆明西山区:“双招双引”推动人才链和产业链融合发展
为激励党员干部在营商环境建设中担当作为,昆明市西山区深入实施人才强区战略和人才领跑工程,建立健全招商引资和招才引资并轨新模式,以产
2022-03-19
绥化望奎以工业化思维为引领 推动肉类加工制造产业腾飞
望奎县以工业化思维为引领,推动全县以生猪为主的肉类加工制造产业一年全面开局、三年基本成势、五年产业腾飞,聚焦五化做强做优肉类加工制
2022-03-19
  中新网海口1月23日电(符宇群)海南省第六届人民代表大会第五次会议23日在海口举行第二次全体会议。海南省人民检察院检察长张毅在作报告
2022-01-24
  中新网太原1月23日电 (高雨晴 冉涌 张鹏宇)记者23日从国网山西省电力公司获悉,该公司冬奥保电应急发电队伍已到达河北张家口赛区,
2022-01-24
  中新网西宁1月23日电 (记者 李江宁)据青海省地震局23日消息,中国地震台网正式测定,北京时间2022年1月23日10时21分,在青海海西州德
2022-01-24
  中新网贵阳1月23日电 (周燕玲)对外开放,是内陆开放型经济试验区贵州正在召开的两会热点词汇,如何拓展海内外“朋友圈”助力贵州经济
2022-01-24
温馨生活好young 厦门推广文旅产品火爆全网
  中新网厦门1月23日电 (记者 杨伏山)“冬日暖阳厦门好young”福建省内宣传推广线下活动22日精彩收官。主办方称,本次活动火爆全网及福
2022-01-24
宁夏非遗传承人:刻刀里的守正创新更有“年味”
  (新春见闻)宁夏非遗传承人:刻刀里的守正创新更有“年味”  中新网银川1月23日电 题:宁夏非遗传承人:刻刀里的守正创新更有“年味
2022-01-24
沧州:8个重大科技专项项目确定 引领经济社会高质量发展
为充分发挥科技在经济社会高质量发展中的引领和支撑作用,沧州市确定8个项目为2021年全市重大科技专项项目。这8个重大科技专项项目分别为:
2022-03-19
  中新网海口1月23日电(王子谦 符宇群)海南省高级人民法院院长陈凤超23日说,2021年海南法院为自贸港建设提供坚强司法保障,全年有效管
2022-01-24
  新华社武汉1月23日电(记者王贤)随着春节假期临近,从广州、深圳等地返回湖北的旅客较多。为此,23日,武汉站、汉口站、襄阳东站、十堰
2022-01-24
  1月22日0—24时,广东省新增本土确诊病例3例和本土无症状感染者1例,均为珠海报告。23日,珠海市疫情防控新闻发布会上,珠海市政府副秘
2022-01-24
青海海西州德令哈市发生3.7级地震
  据中国地震台网正式测定,1月23日11时58分在青海海西州德令哈市发生3 7级地震,震源深度9千米,震中位于北纬38 40度,东经97 35度。
2022-01-24
  北京2022年冬奥会和冬残奥会颁奖花束已于近期完成交付。与传统的鲜切花不同,这些花束全部采用上海市非物质文化遗产“海派绒线编结技艺
2022-01-24
  中新网宿迁1月23日电 (刘林 张华东)核酸检测是当下及时发现潜在感染者、阻断疫情传播的有效方法。23日,记者从宿迁市宿豫区警方获悉
2022-01-24
  记者从天津市人社局获悉,从明天(24日)起,天津2022年度第一期积分落户申报工作正式开始,这是新修订的《天津市居住证管理办法》《天津
2022-01-24
  中新社北京1月23日电 (记者 刘亮)记者23日从中国海关总署获悉,2021年,中国海关组织开展“国门绿盾”专项行动,在寄递、旅客携带物
2022-01-24
  记者从天津市疫情防控指挥部获悉,天津疫情第341—360例阳性感染者基本信息公布。  目前,这20例阳性感染者已转运至市定点医院做进一
2022-01-24
“最美基层民警”武文斌:案子破了最管用
  中新网吕梁1月23日电 题:“最美基层民警”武文斌:案子破了最管用  作者 高瑞峰  同事称他为“拼命三郎”。从警14年,武文斌破
2022-01-24
  据“西安发布”消息,截至2022年1月23日,雁塔区长延堡街道近14天内无新增本地病例和聚集性疫情。根据国务院联防联控机制关于分区分级
2022-01-24
  中新网西宁1月23日电 (记者 孙睿)据青海省地震台网测定,2022年1月23日10点21分(北京时间)在青海省海西州德令哈市(北纬38 44度,东经
2022-01-24
江西南昌:市民赏年画迎新年 书法家挥毫送春联
  (新春见闻)江西南昌:市民赏年画迎新年 书法家挥毫送春联  1月23日,“赏年画过大年”新年画作品联展江西南昌站活动在江西省文化馆
2022-01-24
  中新网成都1月23日电 (祝欢)成都市第十七届人民代表大会第六次会议23日在成都举行,成都市中级人民法院院长郭彦与成都市人民检察院检
2022-01-24
列车临时停车3分钟救旅客
  (新春见闻)列车临时停车3分钟救旅客  中新网广州1月23日电 (郭军 黄伟伟)“车长,车长,4号车厢有位旅客腹涨难忍,身体不舒服”…
2022-01-24
女子背负命案潜逃24年 因涉疫人员核查落网
  中新网湖州1月23日电(施紫楠 徐盛煜 赵学良)1998年7月,犯罪嫌疑人杜某因家庭琐事,用菜刀将自己的弟媳砍伤致死。案发后,她从老家河
2022-01-24
广东“00后”雄狮少年锤炼功夫迎新春
  (新春见闻)广东“00后”雄狮少年锤炼功夫迎新春  中新社广州1月23日电 题:广东“00后”雄狮少年锤炼功夫迎新春  作者 孙秋霞 
2022-01-24
03-19 2022岳阳国际旅游节开幕 特色农产品展销等系列活动目不暇接
2022岳阳国际旅游节开幕 特色农产品展销等系列活动目不暇接
今天,天下洞庭岳阳市君山区第九届良心堡油菜花节暨2022岳阳国际旅游节开幕,菊红、粉红、水红、桃红、紫色、白色等七色组成的4万亩花海在 [详细]
03-19 2022年郴州计划重点推进文旅项目101个 总投资354亿元
2022年郴州计划重点推进文旅项目101个 总投资354亿元
3月16日,我市举行全市文旅项目和城市大提质大融城项目集中开工仪式,市委书记吴巨培宣布项目开工。郴州嘉合欢乐世界、仙福路工地清风徐来 [详细]
03-19 宿州泗县深入推进文旅融合发展 擦亮城市品牌
宿州泗县深入推进文旅融合发展 擦亮城市品牌
近年来,泗县以争创安徽省文化旅游名县为目标,深入推进文旅融合发展,努力擦亮水韵泗州 运河名城城市品牌,全县文化旅游业实现高质量发展 [详细]
03-19 淡季不忘引流 京郊民宿市场有望迎来回暖
淡季不忘引流 京郊民宿市场有望迎来回暖
旅游淡季中的京郊民宿有望成为市场中最先复苏的板块。3月17日,北京商报记者调查发现,虽然正值旅游淡季,且受疫情变化的影响,不过各家民 [详细]
01-24 西安浐灞回应“社区领导怒怼咨询群众”:涉事社区主任已停职
西安浐灞回应“社区领导怒怼咨询群众”:涉事社区主任已停职
  西安浐灞回应“一社区领导在市民咨询离市政策时发生争执”事件 涉事社区主任已停职  西部网讯(记者 刘望)日前,网络上流传一条视频 [详细]
01-24 宁夏:“草根主播”把货卖 “线上赶集”年味浓
宁夏:“草根主播”把货卖 “线上赶集”年味浓
  (新春走基层)宁夏:“草根主播”把货卖 “线上赶集”年味浓  中新网宁夏红寺堡1月23日电 题:宁夏:“草根主播”把货卖 “线上赶 [详细]
01-24 西安:整区解封前24小时内进行不漏一人的全员核酸检测
西安:整区解封前24小时内进行不漏一人的全员核酸检测
  1月23日15时,陕西省政府新闻办公室举行陕西省新冠肺炎疫情防控工作第四十五场新闻发布会。陕西省卫生健康委员会党组成员、省中医药管 [详细]