前言

源自于晓晨在成都.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. PE文件格式详解(七)

    PE文件格式详解(七)   Ox00 前言 前面好几篇在讲输入表,今天要讲的是输出表和地址的是地址重定位.有了前面的基础,其实对于怎么找输出表地址重定位的表已经非常熟悉了.   0x01 输出表结构 ...

  2. MYSQL 之 JDBC(十七): 调用函数&存储过程

    1.通过Connection对象的prepareCall()方法创建一个CallableStatement对象的实例.在使用Connection对象的preparedCall()方法时,需要传入一个S ...

  3. .NET Core 跨平台

    前言   .NET Core是一个开源的模块化的Framework,不管是开发web或移动设备都在同一个Framework(.NET Core)下运行,而且 .NET Core也可在不同的操作系统上运 ...

  4. 自定义类支持foreach

    建议使用yield语句简化迭代 using System; using System.Collections; namespace 自定义类实现foreach { class A { int[] w; ...

  5. static关键字真能提高Bean的优先级吗?答:真能

    生命太短暂,不要去做一些根本没有人想要的东西.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习 ...

  6. Oracle RMAN 异机恢复一例

    背景介绍:本例需求是将NBU备份的oracle数据库恢复到另一主机上. NBU环境配置.异机上的Oracle软件安装配置忽略,下面只介绍OracleDB恢复的过程. ----------------- ...

  7. Apache 阿帕奇 配置运行环境

    阿帕奇 Apache 是一个很常用的服务器环境. 安装阿帕奇后,需要对配置文件进行修改,才能使用. https.conf是阿帕奇的配置文件,地址在 阿帕奇的安装目录\conf\httpd.conf 默 ...

  8. 阿里云如何使用二次验证码/虚拟MFA/两步验证/谷歌验证器?

    阿里云如何使用二次验证码/虚拟MFA/两步验证/谷歌验证器? 见如上链接中视频

  9. springboot 跨域设置

    /** * Configuration cors */ @Configuration public class MyConfiguration { @Bean public FilterRegistr ...

  10. js异步执行原理

    我们都知道js是一个单线程的语言,所以没办法同时执行俩个进程.所以我们就会用到异步. 异步的形式有哪些那,es5的回调函数.es6的promis等 异步的运行原理我们可以先看下面这段代码 应该很多人都 ...