前言

源自于晓晨在成都.net社区群的一篇文章 《晓晨的ASP.NET Core 奇淫技巧之伪属性注入》

他的思路是 Ioc容器替换 ControllerActivator,因为只能在控制器内完成属性注入,意识心痒痒,就开笔写了这样一篇

先分析一下属性注入的思路

属性注入的核心就是通过动态代理完成注入,在这个过程中,对源实例的属性/字段注入实体

想了一下,最近几天沉迷学习,没有写点什么技术分享了,又想起之前学习AspectCore的过程,就打算基于AspectCore制作属性注入


设计思路如下

可以看见无论是默认的特性注入AOP流程,还是我们自定义的代理工厂类,核心都是通过拦截执行过程到自定义的过滤器

个人选择实现的方式是自定义工厂类,也可以根据代码,实现特性注入的方式注入属性

到属性注入这一步,就是查找自定义的特性,有注入的特性的,则完成字段/属性注入


实例实现

属性注入的特性

    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class PropertyInjectAttribute: Attribute
{ }

这个特性,我们约束了只能打在字段/属性上面

自定义过滤器/过滤器工厂类

过滤器

    internal class PropertyInjectInterceptor : IInterceptor
{
public bool AllowMultiple => true; public bool Inherited { get ; set; }
public int Order { get; set; } public Task Invoke(AspectContext context, AspectDelegate next)
{
var instace = context.Implementation;
var instanceType = instace.GetType(); var serviceProvider = context.ServiceProvider; var bindingFlag = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; foreach (var field in instanceType
.GetFields(bindingFlag)
.Where(_field =>
_field.GetCustomAttributes(typeof(PropertyInjectAttribute), true) != null &&
_field.GetCustomAttributes(typeof(PropertyInjectAttribute), true).Length > &&
_field.FieldType.IsInterface
)
)
{
var value = field.GetReflector().GetValue(instace); if (value == null)
{
var service = serviceProvider.GetRequiredService(field.FieldType); field.GetReflector().SetValue(instace, service);
}
} foreach (var property in instanceType
.GetProperties(bindingFlag)
.Where(_property =>
_property.GetCustomAttributes(typeof(PropertyInjectAttribute), true) != null &&
_property.GetCustomAttributes(typeof(PropertyInjectAttribute), true).Length > &&
_property.PropertyType.IsInterface
)
)
{
var value = property.GetReflector().GetValue(instace); if (value == null)
{
var service = serviceProvider.GetRequiredService(property.PropertyType); property.GetReflector().SetValue(instace, service);
}
} return next(context);
}
}

过滤器工厂类

    public class PropertyInjectInterceptorFactory : InterceptorFactory
{
public override IInterceptor CreateInstance(IServiceProvider serviceProvider)
{
return serviceProvider.GetRequiredService<PropertyInjectInterceptor>();
}
}

启用过滤器工厂类

            services.AddScoped<PropertyInjectInterceptor>();
services.ConfigureDynamicProxy(config =>
{
config.Interceptors.Add(new PropertyInjectInterceptorFactory());
}); return services.BuildDynamicProxyProvider();

编写测试例子

    public interface IInterface
{
void Hello();
} internal class InterfaceService : IInterface
{
[PropertyInject]
private IPropertyServer propertyServer; [PropertyInject]
private IPropertyServer _propertyServer { get; set; } public void Hello()
{
Console.WriteLine("Hello");
}
} [NonAspect]
public interface IPropertyServer
{ } internal class PropertyServer: IPropertyServer
{ }

属性注入的实现,我不想再被AOP代理一次,就打上了NopAspect特性,如果不介意的话,也可以不打


后话

我隐隐约约记得AspectCore是自带了属性注入的,奈何最近几天没写C#代码了,有点想念,就自己撸上,重复造轮子了

分享嘛,思路最重要,使用而言,有成熟的轮子肯定不要自己造,学习的话,就要有勇于造轮子的心思

打个小广告

如果有技术交流可以加NCC的群 24791014、436035237,我在群里,有任何关于asp.net core方面的问题或者建议都可以与我交流,非常欢迎

附上晓晨的链接

《ASP.NET Core 奇淫技巧之伪属性注入》

https://www.cnblogs.com/stulzq/p/12610026.html

基于AspectCore打造属性注入的更多相关文章

  1. 基于autofac的属性注入

    基于autofac的属性注入 什么是属性注入 在了解属性注入之前,要先了解一下DI(Dependency Injection),即依赖注入.在ASP.NET Core里自带了一个IOC容器,而且程序支 ...

  2. Java框架spring 学习笔记(六):属性注入

    属性注入:创建对象的时候,向类里面的属性设置值. Java属性注入有三种方法: 使用set方法注入 有参数构造注入 使用接口注入 Spring框架里面的属性注入方式 有参数构造属性注入 set方法属性 ...

  3. spring的基于XML方式的属性注入

    1.掌握spring的属性注入的方法: 1.1构造方法注入普通值---------<constructor-arg>标签的使用 首先新建一个类 package spring.day1.de ...

  4. Spring:特殊数据类型的属性注入(基于配置文件)

    该处提到的特殊数据类型指的是除了基础数据类型和String以外的其他常用的数据类型,如:List.Map.Set.以及pojo对象等.则我们创建的Person类定义为: package bjtu.we ...

  5. 详解 Spring 3.0 基于 Annotation 的依赖注入实现(转)

    使用 @Repository.@Service.@Controller 和 @Component 将类标识为 Bean Spring 自 2.0 版本开始,陆续引入了一些注解用于简化 Spring 的 ...

  6. 详解 Spring 3.0 基于 Annotation 的依赖注入实现--转载

    使用 @Repository.@Service.@Controller 和 @Component 将类标识为 Bean Spring 自 2.0 版本开始,陆续引入了一些注解用于简化 Spring 的 ...

  7. spring3——IOC之基于XML的依赖注入(DI )

    我们知道spring容器的作用是负责对象的创建和对象间关系的维护,在上一篇博客中我们讲到spring容器会先调用对象的无参构造方法创建一个空值对象,那么接下来容器就会对对象的属性进行初始化,这个初始化 ...

  8. SSM-Spring-07:Spring基于注解的di注入

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 注解: 说起注解,哇哦,每个人都或多或少的用到过 像什么@Overried,@Test,@Param等等之前就 ...

  9. 基于配置文件的Spring注入

    基于配置文件的Spring注入 1.依赖注入的概述 依赖注入指的是通过Spring配置文件的方式创建对象时,直接通过配置的方式将数据注入到该对象的标量类型属性,并从Spring容器中获取指定对象注入到 ...

随机推荐

  1. 通过注入DLL后使用热补丁钩取API

    通过注入DLL后使用热补丁钩取API 0x00 对比修改API的前五个字节钩取API 对前一种方法钩取API的流程梳理如下: 注入相应的DLL 修改原始AI的函数的前五个字节跳往新函数(钩取API) ...

  2. CSS的引入与选择器

    CSS的引入与选择器 CSS与HTML的关系 Cascading Style Sheet 即层叠样式表 在上一篇文中,已经介绍了一些非常常用的HTML标签,接下来将步入CSS的学习,如果将单纯HTML ...

  3. Navigation Nightmare POJ - 1984

    Navigation Nightmare Farmer John's pastoral neighborhood has N farms (2 <= N <= 40,000), usual ...

  4. DVWA学习记录 PartⅣ

    File Inclusion 1. 题目 File Inclusion,意思是文件包含(漏洞),是指当服务器开启allow_url_include选项时,就可以通过php的某些特性函数(include ...

  5. 2-ADC

  6. scala 数据结构(八 ):-map映射操作

    在Scala中可以通过map映射操作来解决: 将集合中的每一个元素通过指定功能(函数)映射(转换)成新的结果集合这里其实就是所谓的将函数作为参数传递给另外一个函数,这是函数式编程的特点 以HashSe ...

  7. java 面向对象(二十六):枚举类的使用

    1. 枚举类的说明:* 1.枚举类的理解:类的对象只有有限个,确定的.我们称此类为枚举类* 2.当需要定义一组常量时,强烈建议使用枚举类* 3.如果枚举类中只一个对象,则可以作为单例模式的实现方式. ...

  8. 机器学习实战基础(二十二):sklearn中的降维算法PCA和SVD(三) PCA与SVD 之 重要参数n_components

    重要参数n_components n_components是我们降维后需要的维度,即降维后需要保留的特征数量,降维流程中第二步里需要确认的k值,一般输入[0, min(X.shape)]范围中的整数. ...

  9. 基于svg的环形进度条

    其实需求是这么一个基于日期的环形进度条,开始用css3写了一下感觉太麻烦了,于是抽了点时间用svg画了一个. 不多说 上代码: css: <style> circle { -webkit- ...

  10. As 布局文件太多很乱的问题

    //添加自定义文件整理文件夹的方法,没有之一在build.gradle(Module: app)里加入布局需要放入的路径代码>>>>>> sourceSets { ...