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的对象

c5e648868a18f2dff9b2c63fde708f86.png

下面来讲讲使用方法:

ConditionOnBean和ConditionOnMissingBean

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

  1. ConditionOnBean的意思是,如果指定的类已经被注册的话,我才要注册。

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

上面的代码的意思是,如果Test10Model3被注册的话,才会注册Test10Model5

  1. 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上面,该注解的参数需要填入类的完整名称

  1. ConditionOnClass的意思是如果当前运行环境存在指定的类的话,就注册

[Bean]
[ConditionOnClass("Autofac.Annotation.Test.Test10Model2,Autofac.Configuration.Test")]
public Test10Model6 getTest10Model6()
{//找的到class 所以可以注册Test10Model6Console.WriteLine("registered Test10Model6");return new Test10Model6();
}
  1. 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"
}
  1. 里面存在指定的key为xxx时就注册

[Bean]
[ConditionalOnProperty("onproperty", "on")]
public Test10Model8 getTest10Model8()
{//因为配置文件onproperty的值为on 所以会注册Console.WriteLine("registered Test10Model8");return new Test10Model8();
}
  1. 或者不存在指定的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也是上面几个其他注解的父类

d39e84de43d9000132941ea164b87ee7.png
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


我是正东,学的越多不知道也越多。写代码的乐趣在于你可以展现你发现的美。

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

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

相关文章

公众平台关注用户达到5万即可开通流量主功能 可以推广APP应用

今天微信公众平台发布发布了一些更新&#xff0c;公众帐号的关注用户达到5万&#xff0c;即可开通流量主功能&#xff0c;之前的是要求10万粉丝&#xff0c;这是一个微信开放的信号。广告主可推广苹果商店应用或腾讯开放平台应用。新增卡片和图文广告规格。以下是微信团队的公告…

二进制全排列 java_排列组合算法真厉害,傻瓜都能学会

作者&#xff1a;枕边书来源&#xff1a;https://zhenbianshu.github.io/2019/01/charming_alg_permutation_and_combination.html需求最近工作中碰到一个需求&#xff1a;我们的数据表有多个维度&#xff0c;任意多个维度组合后进行 group by 可能会产生一些”奇妙”的反应&am…

Spark ML - 聚类算法

http://ihoge.cn/2018/ML2.html Spark ML - 聚类算法 1.KMeans快速聚类 首先到UR需要的包&#xff1a; import org.apache.spark.ml.clustering.{KMeans,KMeansModel} import org.apache.spark.ml.linalg.Vectors 开启RDD的隐式转换&#xff1a; import spark.implicits.…

twitter storm源码走读(五)

TridentTopology创建过程详解 从用户层面来看TridentTopology&#xff0c;有两个重要的概念一是Stream,另一个是作用于Stream上的各种Operation。在实现层面来看&#xff0c;无论是stream&#xff0c;还是后续的operation都会转变成为各个Node&#xff0c;这些Node之间的关系通…

C语言宏使用常见问题

代码&#xff1a; #include<stdio.h> #define MAX(a,b) a>b?a:b #define MIN(a,b) a>b?b:a //#define M (xY) #define M1(m) m*m #define M2(m) (m)*(m) #define M3(m) ((m)*(m)) int main(){int x,y,max,min;printf("Input one numbers:");int sum, m…

ad域管理与维护_AD域管理员账号下发

大家好&#xff0c;最近比较忙&#xff0c;好久没发文章了&#xff0c;这次继续讲AD域的相关内容。AD域运行在Windows Server服务器&#xff0c;用于集中管理网内的所有Windows客户端主机&#xff0c;其中最重要的管理手段便是「域组策略」&#xff0c;可管理的条目非常多&…

java中main函数解析

作者&#xff1a;xwdreamer出处&#xff1a;http://www.cnblogs.com/xwdreamer欢迎任何形式的转载&#xff0c;但请务必注明出处。从写java至今&#xff0c;写的最多的可能就是主函数 public static void main(String[] args) {} 但是以前一直都没有问自己&#xff0c;为什么要…

逻辑回归算法原理

http://ihoge.cn/2018/LR.html 逻辑回归模型 逻辑回归也被称为对数几率回归&#xff0c;算法名虽然叫做逻辑回归&#xff0c;但是该算法是分类算法&#xff0c;个人认为这是因为逻辑回归用了和回归类似的方法来解决了分类问题。 逻辑回归模型是一种分类模型&#xff0c;用条…

.net core入门之web应用

2019独角兽企业重金招聘Python工程师标准>>> 其实铺垫了那么久&#xff0c;终于到重点了&#xff0c;迫不及待了吧&#xff0c;那么我们用重量级工具Visual Studio 2015&#xff0c;安装Update3&#xff0c; 安装DotNetCore.1.0.1-VS2015Tools.Preview2.0.2.exe&…

python里split_python中split()的用法

原博文 2018-10-19 15:15 − Python split() 通过指定分隔符对字符串进行切片&#xff0c;如果参数 num 有指定值&#xff0c;则仅分隔 num 个子字符串。 语法&#xff1a; str.split(str"", numstring.count(str)) str -- 分隔符&#xff0c;默认为所有的空字符&…

设计模式之-命令模式(Command Pattern)

命令模式&#xff08;Command Pattern&#xff09;是用来实现在一个请求 - 响应模型松耦合。在命令模式中&#xff0c;请求被发送给调用者和调用它传递给被封装的命令对象。 Command对象将请求传递到接收器的适当的方法来执行特定操作。客户端程序创建接收器对象&#xff0c;然…

android -上传文件到服务器

android上传文件到服务器 重点:最好是设置好content-type这些参数的配置&#xff01; package com.spring.sky.image.upload.network; import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.Inp…

梯度下降法、随机梯度下降法、批量梯度下降法及牛顿法、拟牛顿法、共轭梯度法

http://ihoge.cn/2018/GradientDescent.html http://ihoge.cn/2018/newton1.html 引言 李航老师在《统计学习方法》中将机器学习的三要素总结为&#xff1a;模型、策略和算法。其大致含义如下&#xff1a; 模型&#xff1a;其实就是机器学习训练的过程中所要学习的条件概率…

浅谈.NET 6 中 gRPC 的最新功能

gRPC 是一个现代的、跨平台的、高性能的 RPC 框架。gRPC 是构建在 ASP.NET Core 之上&#xff0c;也是我们推荐的使用 .NET 构建 RPC 服务的方法。.NET 6 进一步提高了 gRPC 已经非常出色的性能&#xff0c;并添加了一系列新功能&#xff0c;使 gRPC 在现代云原生应用程序中比以…

如果你没有时间读书,至少要保留这个习惯

全世界只有3.14 % 的人关注了爆炸吧知识快节奏的生活中&#xff0c;如何花费少量的时间&#xff0c;就可以让自己的生活发生好的改变&#xff1f;知乎上有一个高赞回答&#xff1a;大量阅读优质文章。见识决定了你的眼界&#xff0c;站得越高&#xff0c;看得越多&#xff0c;你…

C++ 标准模板库

转载于:https://www.cnblogs.com/Flyzhcong/p/3977865.html

.NET Conf 2021 回顾

.NET Conf 2021是有史以来规模最大的.NET Conf,全球演讲者举办了80多场会议!我们非常感谢所有收看直播、在分享会上的提问、参与我们的乐趣和游戏的人。学习将持续到1月底&#xff0c;社区活动将持续进行&#xff0c;所以一定要查看这些活动&#xff0c;并关注我们的会议 GitHu…