在.net core中实现字段和属性注入的示例代码
var serviceType = serviceAttribute.ServiceType; if (serviceType == null && serviceAttribute.InterfaceServiceType) { serviceType = type.GetInterfaces().FirstOrDefault(); } if (serviceType == null) { serviceType = type; } switch (serviceAttribute.Lifetime) { case ServiceLifetime.Singleton: services.AddSingleton(serviceType, type); break; case ServiceLifetime.Scoped: services.AddScoped(serviceType, type); break; case ServiceLifetime.Transient: services.AddTransient(serviceType, type); break; default: break; } 我们起首搜查serviceAttribute.ServiceType,假若有值的话,它就是注册处事的范例,假如没有的话,看是否应承从接口中获取处事范例,假如应承,便实行获取第一个作为处事范例,假如还没获取到,就把自身的范例作为处事范例。 第一种环境不常见,非凡环境才会指定ServiceType,由于写起来贫困; 第二种环境合用于依靠抽象编程的同窗,留意这里只取第一个接口的范例; 第三种环境就是合用于像我这种有不良风俗的患者(依靠实现编程)! 到此为止我们的处事注册已经接头完了,下面看看怎样获取。 字段和属性注入 这里我们说的获取,不是框架默认容器提供的结构器注入,而是要实现字段和属性注入,先看看结构器注入是什么样的: public class HomeController : Controller { UserService userService; OrderService orderService; MsgService msgService; OtherService otherService; OtherService2 otherService2; public HomeController(UserService userService, OrderService orderService, MsgService msgService, OtherService otherService, OtherService2 otherService2) { this.userService = userService; this.orderService = orderService; this.msgService = msgService; this.otherService = otherService; this.otherService2 = otherService2; } } 假如引用的处事不再添加还好,假如编写边添加就太要命了,每次都要界说字段、在结构器要领署名中些添加参数、在结构器中赋值,便捷性和Spring的@autowired注解没法比,以是我们要客气进修,创作更便捷的操纵。 [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public class AutowiredAttribute : Attribute { } 这个特征内里什么也没有,首要是下面这个类,装配操纵都在这里: /// <summary> /// 从容器装配service /// </summary> [AppService] public class AutowiredService { IServiceProvider serviceProvider; public AutowiredService(IServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; } public void Autowired(object service) { var serviceType = service.GetType(); //字段赋值 foreach (FieldInfo field in serviceType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { var autowiredAttr = field.GetCustomAttribute<AutowiredAttribute>(); if (autowiredAttr != null) { field.SetValue(service, serviceProvider.GetService(field.FieldType)); } } //属性赋值 foreach (PropertyInfo property in serviceType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { var autowiredAttr = property.GetCustomAttribute<AutowiredAttribute>(); if (autowiredAttr != null) { property.SetValue(service, serviceProvider.GetService(property.PropertyType)); } } } } 我们方才写的[AppService]特征在这里已经用上了,而且这个类行使结构器注入了IServiceProvider。Autowired(object service)要领的参数是要装配的处究竟例,起首获取处事范例,再行使反射查询有AutowiredAttribute特征的字段和属性,我们在结构器注入了serviceProvider,这里便可以行使serviceProvider的GetService要领从容器中获取对应范例的实例来给字段和属性赋值。 整个进程就是这样,简朴明白。开始的时辰我想行使静态类来编写AutowiredService,可是静态类没法注入IServiceProvider,办理要领也有,可以行使定位器模式全局生涯IServiceProvider: /// <summary> /// 处事提供者定位器 /// </summary> public static class ServiceLocator { public static IServiceProvider Instance { get; set; } } 在Setup的Configure要领中赋值: ServiceLocator.Instance = app.ApplicationServices; (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |