前言

源自于晓晨在成都.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. easy tornado

    easy tornado 题目分析 这是一道2018年护网杯的题目 /flag.txt /welcome.txt /hints.txt 一共有3个文件. /flag.txt flag in /flll ...

  2. 数据可视化之 图表篇(二)如何用Power BI制作疫情地图?

    丁香园制作的这个地图可视化,相信大家每天都会看好几遍,这里不讨论具体数据,仅来探讨一下PowerBI地图技术. 这个地图很简洁,主要有三个特征: 1,使用着色地图,根据数据自动配色 2,只显示中国地图 ...

  3. Python网络编程04 /recv工作原理、展示收发问题、粘包现象

    Python网络编程04 /recv工作原理.展示收发问题.粘包现象 目录 Python网络编程04 /recv工作原理.展示收发问题.粘包现象 1. recv工作原理 2. 展示收发问题示例 发多次 ...

  4. python利用selenium(webdriver chrome)模拟登陆获取cookie

    (我是在windows下进行实验的) 准备工作: 1.安装python环境. 2.python安装selenium插件(执行以下命令就行).   pip install selenium 3.Wind ...

  5. 因为喜欢所以升级,MyStaging-3.0 继续

    我为什么维护MyStaging 目前该项目只有我一个人在维护,权当学习交流.为什么要继续维护呢,说一千道一万,还是因为喜欢,由于他的简单易用,从而促使我决定对 MyStaging 进行升级,目前 3. ...

  6. 题解 洛谷 P6349 【[PA2011]Kangaroos】

    先考虑对题目进行转化,我们称两个区间有交集为这两个区间能匹配,每个询问就是在序列中最长能连续匹配的长度. 对序列中的一个区间\([l,r]\)和询问的一个区间\([L,R]\),若满足\(L \leq ...

  7. PHP入门之类型与运算符

    前言 PHP对于大部分人来说,是比较容易入门的.笔者也是刚学习不久,所以就把自己学习的基础知识进行总结和整理.第一部分是类型与运算符.如果你想学习PHP,可以参考PHP学习手册学习,任何一本教学资料也 ...

  8. Python 写入excel时的字体格式设置

    转自:https://blog.csdn.net/kuangzhi9124/article/details/81940919 下面代码设置了单元格的字体.位置居中.框线,可以将格式调成自己需要的 im ...

  9. ken桑带你读源码 之 scrapy_redis

    首先更大家说下  正式部署上线的爬虫会有分布式爬虫的需求  而且原本scrapy 的seen (判断重复url的池  不知道用啥词  已抓url吧 )  保存在磁盘 url 队列 也是保存在磁盘 (保 ...

  10. Day09_商品管理

    学于黑马和传智播客联合做的教学项目 感谢 黑马官网 传智播客官网 微信搜索"艺术行者",关注并回复关键词"乐优商城"获取视频和教程资料! b站在线视频 0.学习 ...