把Autofac玩的和java Spring一样6

大家好,今天来介绍我开源的一个autofac.Annotation项目 源码:https://github.com/yuzd/Autofac.Annotation

  • 本项目是autofa的一个扩展组件,autofac是一个老牌的DI容器框架 ,支持netframework和netcore

  • Annotdation是注解的意思,在java项目里面 注解的概念和 csharp里面的 Attribute 的概念是一样的。

本项目的目的 降低玩DI容器的门槛,快速实现依赖注入 自动装配 以及拦截器,AOP切面编程

基于参考 Java的 Spring注解方式开发思想,

所有autofac容器的注册 和 装配 都是依赖标签来完成。

这样一来 一方面很容易分清楚 哪些是DI 哪些非DI, 哪些是拦截器,哪些需要拦截器,轻松实现切面编程, 代码也好看,吸收java的spring框架的优越的地方,配合.net语法的优越性,编程效率能够大大提升。

支持的标签一览

标签名称使用位置使用说明
AutoConfiguration打在class上面自动装配class里面带有Bean标签的方法
Bean打在方法上面配合AutoConfiguration标签使用
Component打在class上面自动注册
Autowired打在构造方法的Parameter,类的Property,类的Field自动装配
PropertySource打在class上面配合Value标签使用,设置Value的数据源,支持json,xml,支持资源内嵌
Value打在构造方法的Parameter,类的Property,类的Field静态数据装配,支持强大的EL表达式
Aspect打在class上面开启拦截器,默认注册为类拦截器,也可以指定为接口型拦截器(和pointcut的区别是它是打在哪个class哪个才会生效)
Pointcut打在class上面切面配置,一个切面拦截N多个对象

针对每个标签的使用文档 请移步wiki文档传送门

https://github.com/yuzd/Autofac.Annotation/wiki

 

下面介绍一下最最常用的功能也就是注册和自动装配

 

Componet标签把类型注册到DI容器

原理解释

框架会扫描打了Componet标签的class。如果Componet标签里面指定了要注册的类型,则会只注册为这个类型到DI容器。如果没有指定则会把当前class(参考下面的4),以及父类,以及接口都会注册到DI容器(参考下面的1,2和3)。

如何修改这个默认配置呢,比如关闭自动注册父类和接口。可以参考 https://github.com/yuzd/Autofac.Annotation/issues/11

Componet有哪些属性

属性名称类型含义
ServiceType注册指定单个的类型
KeyString注册指定单个的key(为了同个类型注册多次避免歧义)
ServicesType[]注册指定多个的类型
KeysString[]注册指定多个的key(如果指定多个类型又想避免歧义可以搭配上面一起使用)
AutofacScopeEnum

InstancePerDependency(每次都是一个新实例,默认) SingleInstance(单例)

InstancePerLifetimeScope(每个scope获取新的实例) InstancePerRequest(根据每个请求一个实例)

可以在插件初始化的时候指定一个默认的 参考下方的截图说明

AutoActivatebool当指定Scope为单例的时候 默认false 当DI容器初始化完成后会自动完成实例化
InitMethodstring当实例化后自动执行的方法名称
DestroyMethodstring当实例会DI容器回收会自动执行的方法名称
OwnershipEnumLifetimeScope(DI容器管理自动回收策略,默认)External(自己手动管理实例回收)
InterceptorType指定拦截器类型
InterceptorTypeEnumInterface(使用接口模式) Class(使用class的虚方法模式)
InterceptorKeystring如果同一个类型的拦截器有多个 可以指定Key
InjectPropertyTypeEnum属性自动装配的类型 ,Autowired(代表打了Autowired标签的才会装配),All(代表全部自动装配)

Componet的常用构造方法

  1. 默认的构造方法


//默认的构造方法会把当前class,以及父类,以及接口都会注册到DI容器
//这里只会注册A8到DI容器
[Component]
public class A8
{}//通过A8类型可以装配成功
[Autowired]
public A8 A8 { get; set; }·························································public class B
{}//这里会把A8 和 B 都注册到DI容器
[Component]
public class A8:B
{}//通过A8类型可以装配成功
[Autowired]
public A8 A8 { get; set; }//通过B类型也可以装配成功拿到的是A8类型
[Autowired]
public B B { get; set; }
··························································public interface IA
{}public interface IB:IA
{}public class B:IB
{}//这里会把A8  B IB IA 全都注册到DI容器 
//如果你指向注册A8 可以参考https://github.com/yuzd/Autofac.Annotation/issues/11 去配置
[Component]
public class A8:B
{}//通过A8类型可以装配成功 
[Autowired]
public A8 A8 { get; set; }//通过B类型也可以装配成功拿到的是A8类型
[Autowired]
public B B { get; set; }//通过IB类型也可以装配成功拿到的是A8类型
[Autowired]
public IB IB { get; set; }//通过IA类型也可以装配成功拿到的是A8类型
[Autowired]
public IA IA { get; set; }
  1. 注册为指定类型

publicclassB
{}//这个构造方法就是将A6注册为B类型
[Component(typeof(B))]
publicclassA6:B
{}//可以通过下面的方式自动装配 因为上面注册的是B类型 通过B类型可以装配成功 拿到的是A6类型
[Autowired]
public B B { get; set; }//通过下面的方式自动装配会失败 会失败 会失败
[Autowired]
public A6 A6 { get; set; }
  1. 同一个注册类型有多个 采用Key方式解决歧义


public interface ITestAutowiredModal
{
}// ITestAutowiredModal这个类型被注册多个了 避免歧义用"abc"来解决
[Component("abc")]
public class TestAutowiredModal1:ITestAutowiredModal
{
}// ITestAutowiredModal这个类型被注册多个了 避免歧义用"def"来解决
[Component("def")]
public class TestAutowiredModal2:ITestAutowiredModal
{
}//可以用下面的方式来自动装配 拿到的是TestAutowiredModal1类型对象
[Autowired("abc")]public ITestAutowiredModal TestAutowiredModal1 { get; set; }//如果不指定的话会先尝试根据byType模式匹配,因为是指定了Key 所以根据byType拿不到,拿不到就会再次根据属性名称 “abc” 去匹配,就和上面的方式一样了
[Autowired]public ITestAutowiredModal abc { get; set; }//可以用下面的方式来自动装配 拿到的是TestAutowiredModal2类型对象
[Autowired("def")]public ITestAutowiredModal TestAutowiredModal2 { get; set; }

1. 把一个类型注册到DI容器

  • 上面的例子就是把Student类型注册到容器

2. 把当前类型和父类注册到DI容器

  • 上面的例子就是把Student2类型注册到容器

  • 并且把Person类型也注册到容器根据Person类型拿到的是Student2的实体

3. 把当前类型和接口注册到DI容器

  • 上面的例子就是把Student3类型注册到容器

  • 并且把ISay也注册到容器根据ISay类型拿到的是Student3的实体

4. 当继承了父类或者接口 想要指定注册类型怎么办?

  • 上面的例子就是只能通过ISay拿到Student3的实体

  • 不能通过Student3类型拿到!!

5. 怎么指定实例是单例,每次都是新的实例,还是每个Scope一个实例呢?

  • 如上图所示 可以指定AutofacScope属性

  • 如果不指定就是每次获取的一个新的实例

6. 当同一个类型多次注册,如何区分得到我想要的?

  • 如上图 ISay类型有2个实现类 Student3 和 Student4 分别指定了 Key的值

  • 通过ISay + “Student3” 可以获取到 Student3的实体

  • 通过ISay + “Student4” 可以获取到 Student4的实体

7.支持注册类型可以自动实例化对象

  • 如上所示,设定AutoActivate = true代表是启动自动实例化

  • AutofacScope = AutofacScope.SingleInstance 代表单例模式

  • Student5类型会对象会自动实例化 并且以单例的方式存储在DI容器内

8.支持设置实例化时运行指定方法

  • 如上所示 设置 InitMethod 和 DestroyMethod

  • 当实例从DI容器初始化时就会调用 InitMethod

  • 当DI容器Dispose的时候会触发调用DestroyMethod

另外

  • InitMethod支持注入

  • DestroyMethod只能是无参数方法

Autowired自动装配

Autowired有哪些属性

属性名称类型含义
NameString搭配Component指定Key的时候使用,消除一个类型被多个注册带来的歧义
Requiredbool默认装载失败会报错 设置为false装载失败不会报错
CircularDependenciesbool是否支持循环注入 默认是false 不支持,插件初始化的时候可以设置一个默认值

 

打在构造方法上 属性

在单例的对象里面Autowired多实例

使用ObjectFactory来实现,和Lazy的区别是 ObjectFactory修饰的每次获取都是从容器里面获取一遍。而Lazy只有首次才会去容器获取。

延迟自动装配Lazy


[Component]
public class TestLazyModel1
{[Autowired]public Lazy<TestAutowiredModal4> TestAutowiredModal4 { get; set; }[Autowired]public TestAutowiredModal3 TestAutowiredModal3 { get; set; }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307981.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

『软件测试5』测开岗只要求会黑白盒测试?NO!还要学会性能测试!

浅谈软件测试中的性能测试一、&#x1f92a;性能测试概念1、为什么要有性能测试&#xff1f;2、性能测试是什么&#xff1f;3、性能测试的目的二、&#x1f910;性能测试指标1、响应时间2、吞吐量3、并发用户数4、TPS(Transaction Per Second)5、点击率6、资源利用率三、&#…

CLR的简单理解

CLR加载程序生成进程&#xff0c;一个进程中可以存在多个线程&#xff0c;当创建一个线程时&#xff0c;会分配1Mb的空间&#xff0c;也就是线程的栈空间&#xff0c;对应jvm的虚拟机堆栈&#xff0c;是线程执行过程中用到的工作内存。这片内存用于方法传递实参&#xff0c;并存…

『软件测试6』bug一两是小事,但安全漏洞是大事!

详解软件测试中的安全测试一、&#x1f4bf;安全测试概念1、安全测试概述2、安全测试与软件生命周期的关系3、常规测试与安全测试的不同&#xff08;1&#xff09;测试目标不同&#xff08;2&#xff09;假设条件不同&#xff08;3&#xff09;思考域不同&#xff08;4&#xf…

我们真的需要JWT吗?

JWT&#xff08;JSON Web Token&#xff09;是目前最流行的认证方案之一。博客园、各种技术公众号隔三差五就会推一篇JWT相关的文章&#xff0c;真的多如牛毛。但我对JWT有点困惑&#xff0c;今天写出来跟大家探讨探讨&#xff0c;不要喷哈。JWT原理本文默认读者已经对JWT有所了…

leetcode面试题 02.07. 链表相交

一:题目 二:思路 1.这道题我们是需要找到一个结点&#xff0c;并且从这个结点往后的结点都相等 2.我们需要将两个链表 右对齐 3.然后将长链表的指针移动到和短链表头结点相同的位置 4.接下来就是比较指针&#xff0c;当一个指针相同也就意味着往后的结点的数值也相等 三:上码…

详解队列在前端的应用,深剖JS中的事件循环Eventloop,再了解微任务和宏任务

队列在前端中的应用一、队列是什么二、应用场景三、前端与队列&#xff1a;事件循环与任务队列1、event loop2、JS如何执行3、event loop过程4、 DOM 事件和 event loop5、event loop 总结四、宏任务和微任务1、引例2、宏任务和微任务&#xff08;1&#xff09;常用的宏任务和微…

终于弄明白了 Singleton,Transient,Scoped 的作用域是如何实现的

一&#xff1a;背景1. 讲故事前几天有位朋友让我有时间分析一下 aspnetcore 中为什么向 ServiceCollection 中注入的 Class 可以做到 Singleton&#xff0c;Transient&#xff0c;Scoped&#xff0c;挺有意思&#xff0c;这篇就来聊一聊这一话题&#xff0c;自从 core 中有了 S…

leetcode142. 环形链表 II(暴力+双链表)

一:题目 二:思路 1.双指针 快慢指针(快指针一次一个结点&#xff0c;慢指针一次两个结点) 2.如果有环的话&#xff0c;那么快慢指针肯定会相遇 3.那么相遇的地点一定在环中 因为如果没有环的话慢指针是永远追不到快指针的 4.接下来就是判断出口在那里&#xff0c;我们定义一个…

动态 Restful API 生成

介绍通常在DDD开发架构中&#xff0c;我们写完服务层需要在控制器中写API&#xff0c;今天介绍一个组件 Plus.AutoApi 可以用它来动态生成 Restful 风格的 WebApi&#xff0c;不用写 Controller。快速使用在你的应用服务层中添加组件Install-Package Plus.AutoApi在 Startup 中…

卷死了!再不学vue3就没有人要你了!速来围观vue3新特性

一文全面了解vue3新特性一、&#x1f636;vue3比vue2有什么优势&#xff1f;二、&#x1f9d0;Vue3升级了哪些重要的功能1、createApp2、emits(父子组件间的通信)&#xff08;1&#xff09;通信方式&#xff08;2&#xff09;举个例子&#x1f330;3、多事件处理4、Fragment5、…

idea报错Class not found (在target中没有生成对应的class文件)

一&#xff1a;问题描述 二:解决 既然他不自动生成&#xff0c;那么我们就手动导入&#xff1b; 点击后应用 然后再次运行我们的测试用例&#xff1b;如果不行 再取消勾选 然后再运行我们的测试用例

敲黑板!vue3重点!一文了解Composition API新特性:ref、toRef、toRefs

一文了解Composition API新特性&#xff1a;ref、toRef、toRefs一、&#x1f64e;如何理解ref、toRef和toRefs1、ref、toRef和toRefs是什么&#xff08;1&#xff09;ref1&#xff09;ref是什么2&#xff09;举个例子&#x1f330;&#xff08;2&#xff09;toRef是什么1&#…

C# 枚举转列表

C# 枚举转列表独立观察员 2020 年 9 月 1 日今天有朋友问我&#xff0c;ComboBox 怎么绑定一个 Enum&#xff0c;其实他的意思是枚举如何转换为列表。想想这确实是一个挺正常的需求&#xff0c;但我一时也只想到遍历&#xff0c;他觉得麻烦&#xff0c;于是我在网上帮忙查了一下…

leetcode242. 有效的字母异位词(两种方法map或数组)

一:题目 二:上码 1:方法一&#xff08;map解法&#xff09; class Solution { public:bool isAnagram(string s, string t) {/**思路:1.分析题意&#xff0c;这个是要判断t中的字符出现次数和s中字符出现的次数相同2.可以用map<char,int>来做*/map<char,int>m1,m…

活久见!月薪30k的小程序全栈开发到底有多难?

10年前&#xff0c;公司的标配是门户网站&#xff0c;造就了一批网站工作室。随着移动互联网大潮兴起&#xff0c;App又成了企业标配&#xff0c;IOS和Android开发赚的盆满钵满。然而App导致的手机内存告急&#xff0c;无止尽的信息推送&#xff0c;让微信小程序应运而生。然而…

卷不动也得继续学!紧跟vue3的步伐,再来get一波进阶新特性!

vue3进阶新特性一、&#x1f4d7;watch和watchEffect1、watch和watchEffect的区别2、举个例子&#xff08;1&#xff09;wtach监听&#xff08;2&#xff09;watchEffect监听二、&#x1f4d8;setup如何获取组件实例&#xff08;1&#xff09;为什么需要获取组件实例&#xff0…

leetcode349. 两个数组的交集(思路+详解)

一:题目 二:上码 class Solution { public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {/**思路:本题我们采用的哈希表数据结构是unordered_set,没有用数组因为我们不确定给出的数组中数值的范围如果 强上会出现空间的大量…

高效掌握新技能的「树型思维」

大家好&#xff0c;我是Z哥。不知道你有没有过这样的困惑&#xff0c;想学习某项新技能&#xff0c;但是很容失败。比如&#xff0c;出于职业发展的考虑&#xff0c;想学习一门新的编程语言&#xff0c;或者想了解一个新的技术框架&#xff1b;又或者看了某些综艺节目后想玩一玩…

vue2的响应式原理学“废”了吗?继续观摩vue3响应式原理Proxy

一文了解Vue3的响应式原理一、&#x1f7e9;回顾Object.defineProperty二、&#x1f7e8;Proxy基本使用三、&#x1f7e6;学习Proxy语法&#xff1a;Reflect四、&#x1f7e7;Vue3如何用Proxy实现响应式1、实现响应式2、Proxy总结&#xff08;1&#xff09;深度监听&#xff0c…

一名“企业定制化人才”的自诉:“我不愿意,但却无可奈何”

这是头哥侃码的第214篇原创几个月前&#xff0c;我曾在大智慧时期的一位同事跟我聊微信&#xff0c;说自己所在的公司这两年业务一直不温不火&#xff0c;而且从19年底就逐渐缩减技术人员。今年上半年又因为疫情的关系&#xff0c;公司干脆直接砍掉了剩余的三个技术部门&#x…