日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Autofac实现有条件的DI

發布時間:2023/12/4 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Autofac实现有条件的DI 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Autofac.Annotation框架是我用.netcore寫的一個DI框架,基于Autofac參考 Spring注解方式所有容器的注冊和裝配,切面,攔截器等都是依賴標簽來完成。

開源地址:https://github.com/yuzd/Autofac.Annotation

本期講的是最新實現的功能

有條件的DI

有些時候我們想要滿足xxx條件才把一個類注冊到容器里面。比如如何切換Services,如果是Spring,可以根據條件注冊Bean和Configuration。所以我參考Spring的條件注解也在我的Autofac.Annotation框架中也實現了以下注解:

注解使用方式備注
Conditional打在class或者方法上面條件加載,自定義實現的
ConditionOnBean打在標有Bean注解的方法上面條件加載
ConditionOnMissingBean打在標有Bean注解的方法上面條件加載
ConditionOnClass打在class或者方法上面條件加載
ConditionOnMissingClass打在class或者方法上面條件加載
ConditionOnProperty打在class或者方法上面條件加載
ConditionOnProperties打在class或者方法上面條件加載
DependsOn可以配合Bean和Component使用A的實例化依賴另一個B的實例化,但是A并不需要持有一個B的對象

下面來講講使用方法:

ConditionOnBean和ConditionOnMissingBean

這2個注解是只能配合Bean注解一起使用,且只能打在方法上面,不能打在class上面

  • ConditionOnBean的意思是,如果指定的類已經被注冊的話,我才要注冊。

  • [AutoConfiguration] public?class?Test10Config {[Bean][ConditionOnBean(typeof(Test10Model3))]public?Test10Model5?getTest10Model5(){Console.WriteLine("registered?Test10Model5");return?new?Test10Model5();}}

    上面的代碼的意思是,如果Test10Model3被注冊的話,才會注冊Test10Model5

  • ConditionOnMissingBean的意思是,如果指定的類沒被注冊的話,我才要注冊。

  • [AutoConfiguration] public?class?Test10Config {[Bean][ConditionOnMissingBean(typeof(Test10Model1))]public?Test10Model3?getTest10Model3(){Console.WriteLine("registered?Test10Model3");return?new?Test10Model3();}}

    上面的代碼的意思是,如果Test10Model1沒被注冊的話,才會注冊Test10Model3

    ConditionOnClass和ConditionOnMissingClass

    這2個注解是配合Compoment或者AutoConfiguration,PointCut等注解一起使用,可以打在class和method上面,該注解的參數需要填入類的完整名稱

  • ConditionOnClass的意思是如果當前運行環境存在指定的類的話,就注冊

  • [Bean] [ConditionOnClass("Autofac.Annotation.Test.Test10Model2,Autofac.Configuration.Test")] public?Test10Model6?getTest10Model6() {//找的到class?所以可以注冊Test10Model6Console.WriteLine("registered?Test10Model6");return?new?Test10Model6(); }
  • ConditionOnMissingClass的意思是如果當前運行環境不存在指定的類的話,就注冊

  • [Bean] [ConditionOnMissingClass("Autofac.Annotation.Test.test10.Test10Model2,xxxx")] public?Test10Model7?getTest10Model7() {//找不到class?所以注冊Test10Model7Console.WriteLine("registered?Test10Model7");return?new?Test10Model7(); }

    ConditionOnProperty和ConditionOnProperties

    這2個注解可以配合Bean,Compoment,AutoConfiguration,PointCut等注解一起使用,可以打在class和method上面

    意思是,如果數據源(讀取當前項目的appsettings.json)

    • 指定的key對應的值為xxx時

    • 或者不存在指定的key

    就注冊

    appsettings.json

    {"onproperty":?"on" }
  • 里面存在指定的key為xxx時就注冊

  • [Bean] [ConditionalOnProperty("onproperty",?"on")] public?Test10Model8?getTest10Model8() {//因為配置文件onproperty的值為on?所以會注冊Console.WriteLine("registered?Test10Model8");return?new?Test10Model8(); }
  • 或者不存在指定的key

  • [Bean] [ConditionalOnProperty("onproperty1",?matchIfMissing?=?true)] public?Test10Model10?getTest10Model10() {//由于配置文件里面沒有onproperty1?所以會注冊Console.WriteLine("registered?Test10Model10");return?new?Test10Model10(); }

    當想要指定多個值同時滿足的話就用ConditionOnProperties,道理是一樣的~!

    Conditional

    這個注解接受一個實現了ICondition接口的Type類型的參數。具體的判斷條件由自己實現(比如上面的幾個條件注解都滿足不了你,那你就用這個注解搭配自定義的條件)

    首先我們定義一個class實現ICondition接口的ShouldSkip方法,下面的類的意思看注釋應該可以明白:

    public?class?Test10Condition?:?ICondition {///?<summary>///?只有當?windows?系統下才被注冊///?</summary>///?<param?name="context"></param>///?<param?name="metadata"></param>///?<returns>返回true代表不滿足條件,那就不會被注冊到容器</returns>public?bool?ShouldSkip(IComponentRegistryBuilder?context,?object?metadata){if?(RuntimeInformation.IsOSPlatform(OSPlatform.Linux)){//是linux系統?就不注冊return?true;}if?(RuntimeInformation.IsOSPlatform(OSPlatform.OSX)){//是mac系統?也不注冊return?true;}//是windows系統?那就注冊return?false;} }

    下面我們來使用上面的條件用Conditional注解打在方法上面,這個條件表明了只有在windows平臺才會將Test10Model1注冊到容器中

    [AutoConfiguration] public?class?Test10Config {[Bean][Conditional(typeof(Test10Condition))]public?Test10Model1?getTest10Model1(){Console.WriteLine("registered?Test10Model1");return?new?Test10Model1();}}

    上面的例子是結合Bean注解一起使用,Conditional注解還可以打在class上面,結合Compoment或者AutoConfiguration注解來實現滿足條件才注冊!

    Conditional也是上面幾個其他注解的父類

    image

    不同的是上面幾個其他注解的構造方法都指定了自己默認的實現類。

    這樣面向接口設計的好處是在注冊的初始化階段針對驗證條件的邏輯就可以統一處理:只搜集 Conditional或者Conditional的子類注解,且約束了條件判斷的類統一得實現ICondition接口。

    DependsOn

    該注解可以配合Bean和Component注解一起使用,和ConditionXXX系列不一樣,是用來表示一個 A的實例化依賴另一個B的實例化, 但是A并不需要持有一個B的對象

    [Bean] [DependsOn(typeof(Test12Bean4))] public?Test12Bean3?get13() {Debug.WriteLine("new?Test12Bean3");return?new?Test12Bean3?{?Hello?=?"world"?}; }[Bean] public?Test12Bean4?get14() {Debug.WriteLine("new?Test12Bean4");result.Add("get14");return?new?Test12Bean4?{?Hello?=?"world"?}; }

    上面的意思是在需要加載Test12Bean3實例(還沒)的時候,由于設置了DependsOn類Test12Bean4,先去加載Test12Bean4

    [Component] [DependsOn(typeof(Test12Bean8))] public?class?Test12Bean7 {public?Test12Bean7(){//Console.WriteLine("然后我在加載")?}public?string?Hello?{?get;?set;?} }[Component] public?class?Test12Bean8 {public?Test12Bean8(){//Console.WriteLine("我先加載")}public?string?Hello?{?get;?set;?} }

    上面的意思是在需要加載Test12Bean7的實例的時候,先去加載Test12Bean8

    好了,有條件的DI介紹到此,更多教程請參考項目wiki(教程很詳細哦,別忘記給個star)

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


    我是正東,學的越多不知道也越多。寫代碼的樂趣在于你可以展現你發現的美。

    總結

    以上是生活随笔為你收集整理的Autofac实现有条件的DI的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。