加入收藏 | 设为首页 | 会员中心 | 我要投稿 衡阳站长网 (https://www.0734zz.cn/)- 数据集成、设备管理、备份、数据加密、智能搜索!
当前位置: 首页 > 站长学院 > Asp教程 > 正文

在.net core中实现字段和属性注入的示例代码

发布时间:2020-08-22 06:43:12 所属栏目:Asp教程 来源:网络整理
导读:这篇文章主要介绍了在.net core中实现字段和属性注入的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们

Autowired(object service)方法的实现虽然简单,但是使用了效率底下的反射,这个美中不足需要改进,以前可以使用晦涩难懂的EMIT来编写,现在有Expression,编写和阅读都简单了好多,并且效率也不比EMIT差,所以我们使用表达式+缓存来改进。Autowired方法要做的就是从容器中取出合适的对象,然后赋值给service要自动装配的字段和属性,据此我们先编写出委托的伪代码:

(obj,serviceProvider)=>{ ((TService)obj).aa=(TAAType)serviceProvider.GetService(aaFieldType); ((TService)obj).bb=(TBBType)serviceProvider.GetService(aaFieldType); ... }

注意伪代码中的类型转换,Expression表达式在编译成委托时是非常严格的,所有转换都不能省。写表达式的时候我习惯先写伪代码,我希望大家也能养成这个习惯!有了伪代码我们可以开始改造AutowiredService类了:

/// <summary> /// 从容器装配service /// </summary> [AppService] public class AutowiredService { IServiceProvider serviceProvider; public AutowiredService(IServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; } Dictionary<Type, Action<object, IServiceProvider>> autowiredActions = new Dictionary<Type, Action<object, IServiceProvider>>(); public void Autowired(object service) { Autowired(service, serviceProvider); } /// <summary> /// 装配属性和字段 /// </summary> /// <param></param> /// <param></param> public void Autowired(object service, IServiceProvider serviceProvider) { var serviceType = service.GetType(); if (autowiredActions.TryGetValue(serviceType, out Action<object, IServiceProvider> act)) { act(service, serviceProvider); } else { //参数 var objParam = Expression.Parameter(typeof(object), "obj"); var spParam = Expression.Parameter(typeof(IServiceProvider), "sp"); var obj = Expression.Convert(objParam, serviceType); var GetService = typeof(IServiceProvider).GetMethod("GetService"); List<Expression> setList = new List<Expression>(); //字段赋值 foreach (FieldInfo field in serviceType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { var autowiredAttr = field.GetCustomAttribute<AutowiredAttribute>(); if (autowiredAttr != null) { var fieldExp = Expression.Field(obj, field); var createService = Expression.Call(spParam, GetService, Expression.Constant(field.FieldType)); var setExp = Expression.Assign(fieldExp, Expression.Convert(createService, field.FieldType)); setList.Add(setExp); } } //属性赋值 foreach (PropertyInfo property in serviceType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { var autowiredAttr = property.GetCustomAttribute<AutowiredAttribute>(); if (autowiredAttr != null) { var propExp = Expression.Property(obj, property); var createService = Expression.Call(spParam, GetService, Expression.Constant(property.PropertyType)); var setExp = Expression.Assign(propExp, Expression.Convert(createService, property.PropertyType)); setList.Add(setExp); } } var bodyExp = Expression.Block(setList); var setAction = Expression.Lambda<Action<object, IServiceProvider>>(bodyExp, objParam, spParam).Compile(); autowiredActions[serviceType] = setAction; setAction(service, serviceProvider); } } }

代码一下子多了不少,不过由于我们前面的铺垫,理解起来也不难,至此自动装配字段和属性的服务已经写好了,下面看看如何使用:

编写服务类,并添加[AppService]特性

[AppService] public class MyService { //functions }

在Setup的ConfigureServices方法中注册应用服务

public void ConfigureServices(IServiceCollection services) { services.AddMvc(); //注册应用服务 services.AddAppServices(); }

在其他类中注入使用,比如Controller中

public class HomeController : Controller { [Autowired] MyUserService myUserService; public HomeController(AutowiredService autowiredService) { autowiredService.Autowired(this); } }

HomeController的构造函数是不是简洁了许多呢!而且再有新的服务要注入,只要定义字段(属性也可以,不过字段更方便)就可以了,注意:我们定义的字段不能是只读的,因为我们要在AutowiredService中设置。我们还用上面的例子,看一下它的威力吧!

public class HomeController : Controller { [Autowired] UserService userService; [Autowired] OrderService orderService; [Autowired] MsgService msgService; [Autowired] OtherService otherService; [Autowired] OtherService2 otherService2; public HomeController(AutowiredService autowiredService) { autowiredService.Autowired(this); } }

感谢您的观看!全文已经完了,我们没有使用第三方容器,也没有对自带的容器大肆修改和破坏,只是在服务类的构造器中选择性的调用了AutowiredService.Autowired(this)方法,为什么是选择性的呢,因为你还可以使用在构造器中注入的方式,甚至混用,一切都好,都不会错乱。

nuget安装:

PM> Install-Package Autowired.Core

git源码:

[Autowired.Core] https://gitee.com/loogn/Autowired.Core

更新:

支持多个AppServiceAttribute,

支持服务唯一标识,通过Identifier指定服务实现

到此这篇关于在.net core中实现字段和属性注入的示例代码的文章就介绍到这了,更多相关.net core 字段和属性注入内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

(编辑:衡阳站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读