前言

源自于晓晨在成都.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. 基于SpringBoot AOP面向切面编程实现Redis分布式锁

    基于SpringBoot AOP面向切面编程实现Redis分布式锁 基于SpringBoot AOP面向切面编程实现Redis分布式锁 基于SpringBoot AOP面向切面编程实现Redis分布式 ...

  2. 仿Neo4j里的知识图谱,利用d3+vue开发的一个网络拓扑图

    项目需要画一个类似知识图谱的节点关系图. 一开始用的是echart画的. 根据https://gallery.echartsjs.com/editor.html?c=xH1Rkt3hkb,成功画出简单 ...

  3. SQLAlchemy04 /SQLAlchemy查询高级

    SQLAlchemy04 /SQLAlchemy查询高级 目录 SQLAlchemy04 /SQLAlchemy查询高级 1.排序 2.limit.offset和切片操作 3.懒加载 4.group_ ...

  4. web前端知识点(webpack篇)

    webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler).当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency gr ...

  5. java中int相除取小数点后两位或限定位数

    java 两个整数相除保留两位小数: http://blog.sina.com.cn/s/blog_624d755d0101cvuq.html java中,当两个整数相除时,由于小数点以后的数字会被截 ...

  6. 转:Oracle 数据泵详解

    一.EXPDP和IMPDP使用说明 Oracle Database 10g引入了最新的数据泵(Data Dump)技术,数据泵导出导入(EXPDP和IMPDP)的作用 1)实现逻辑备份和逻辑恢复. 2 ...

  7. OSCP Learning Notes - Enumeration(4)

    DNS Enumeration 1. Host Tool host is a simple utility for performing DNS lookups. It is normally use ...

  8. OGG19.1 oracle12c到oracle12c经典模式配置实施

    OGG19.1 oracle12c到oracle12c经典和集成模式配置实施 目的说明 本文提供Oracle GoldenGate在Oracle db到Oracle db的数据复制安装配置指导,适用于 ...

  9. Java顺序查找、二分查找

    Java顺序查找.二分查找   查找算法中顺序查找算是最简单的了,无论是有序的还是无序的都可以,只需要一个个对比即可,但其实效率很低. 顺序查找 动图演示 详细代码 // 顺序查找 public st ...

  10. sqlserver——merge用法

    merge集插入,更新,删除于一体,如果要对一个表同时进行插入,更新,删除2个或3三个操作.效率要高于单个操作. merge into tableb b --被操作表using (select id, ...