javascript
把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有哪些屬性
| Service | Type | 注冊指定單個的類型 |
| Key | String | 注冊指定單個的key(為了同個類型注冊多次避免歧義) |
| Services | Type[] | 注冊指定多個的類型 |
| Keys | String[] | 注冊指定多個的key(如果指定多個類型又想避免歧義可以搭配上面一起使用) |
| AutofacScope | Enum | InstancePerDependency(每次都是一個新實例,默認) SingleInstance(單例) InstancePerLifetimeScope(每個scope獲取新的實例) InstancePerRequest(根據每個請求一個實例) 可以在插件初始化的時候指定一個默認的 參考下方的截圖說明 |
| AutoActivate | bool | 當指定Scope為單例的時候 默認false 當DI容器初始化完成后會自動完成實例化 |
| InitMethod | string | 當實例化后自動執行的方法名稱 |
| DestroyMethod | string | 當實例會DI容器回收會自動執行的方法名稱 |
| Ownership | Enum | LifetimeScope(DI容器管理自動回收策略,默認)External(自己手動管理實例回收) |
| Interceptor | Type | 指定攔截器類型 |
| InterceptorType | Enum | Interface(使用接口模式) Class(使用class的虛方法模式) |
| InterceptorKey | string | 如果同一個類型的攔截器有多個 可以指定Key |
| InjectPropertyType | Enum | 屬性自動裝配的類型 ,Autowired(代表打了Autowired標簽的才會裝配),All(代表全部自動裝配) |
Componet的常用構造方法
默認的構造方法
注冊為指定類型
同一個注冊類型有多個 采用Key方式解決歧義
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有哪些屬性
| Name | String | 搭配Component指定Key的時候使用,消除一個類型被多個注冊帶來的歧義 |
| Required | bool | 默認裝載失敗會報錯 設置為false裝載失敗不會報錯 |
| CircularDependencies | bool | 是否支持循環注入 默認是false 不支持,插件初始化的時候可以設置一個默認值 |
?
打在構造方法上 屬性
在單例的對象里面Autowired多實例
使用ObjectFactory來實現,和Lazy的區別是 ObjectFactory修飾的每次獲取都是從容器里面獲取一遍。而Lazy只有首次才會去容器獲取。
延遲自動裝配Lazy
[Component] public class TestLazyModel1 {[Autowired]public Lazy<TestAutowiredModal4> TestAutowiredModal4 { get; set; }[Autowired]public TestAutowiredModal3 TestAutowiredModal3 { get; set; } }總結
以上是生活随笔為你收集整理的把Autofac玩的和java Spring一样6的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 编写第一个 .NET 微服务
- 下一篇: CLR的简单理解