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上面

  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也是上面几个其他注解的父类

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相关推荐

  1. NET Core 3.0 AutoFac替换内置DI的新姿势

    .NET Core 3.0 和 以往版本不同,替换AutoFac服务的方式有了一定的变化,在尝试着升级项目的时候出现了一些问题. 原来在NET Core 2.1时候,AutoFac返回一个 IServ ...

  2. 把Autofac玩的和java Spring一样6

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

  3. Autofac在.NET Core 中的使用

    前言 Autofac 是一款.NET IoC 容器 . 它管理类之间的依赖关系, 从而使应用在规模及复杂性增长的情况下依然可以轻易地修改 ..NET CORE 中也内置了依赖注入,但是有些情况下需要用 ...

  4. BeetleX之FastHttpApi服务使用详解

    BeetleX是一个轻量级高性能的开源TCP通讯应用框架,通过BeetleX可以轻松扩展不同场的TCP应用服务和客户端组件.框架开源地址:https://github.com/IKende/Beetl ...

  5. ASP.NET Core开发者成长路线图

    来源: MoienTajik/AspNetCore-Developer-Roadmap. 2019年ASP.NET Core开发者指南: 你可以在下面找到一张图,该图展示了你可以选取的路径及你想学习的 ...

  6. .NET Core 中的 Generic Host快速使用指南

    本文以自己在工作中学习和使用.net core generic-host 作一个总结. 前言 在创建的ASPNETCORE项目中,我们可以在Main()中看见,我们通过IWebHostBuild创建了 ...

  7. IT 日语学习 2012 06

    1.しおり 1.书签   2.IT用语  bookmark 2.ブランチ 分岐 branch 3.コンディション 条件 4.DI Dependency Injection

  8. 最大流算法模板:EK和dinic算法

    最大流算法模板:EK和dinic算法 一.EK算法模板 #include<iostream> #include<queue> using namespace std; cons ...

  9. CORDIC算法详解(一)- CORDIC 算法之圆周系统之旋转模式( Rotation Mode )

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/Pieces_thinking/arti ...

最新文章

  1. Java五年,已财富自由,美人在手!
  2. 去掉圆角_小米11高清渲染图曝光:蓝色机身 圆角矩形摄像模组
  3. label 标签里面元素点击事件
  4. codeforces 118A-C语言解题报告
  5. SQL Server基本函数
  6. NGINX访问日志和错误日志
  7. 问题解决,心情不错:)
  8. 【Web:Bootstrap框架】简单实现理解
  9. Ubuntu下搭建Hadoop分布式集群
  10. mysql无级分销_无限级分销系统数据库表设计
  11. Bootstrap折叠导航栏
  12. markdown 设置目录跳转的简单方法
  13. JavaScript Lodash 工具库
  14. linux基础教程 ppt,Linux基础教程(1)操作系统基础 PPT
  15. 2022年计算机二级考试WPS Office高级应用与设计考前冲刺题及答案
  16. 华为m6更新鸿蒙吗,华为手机升级鸿蒙的方法,有哪位升级成功的吗?
  17. 简书收入结算与提现常见问题
  18. SASE 的核心能力:安全Web网关
  19. pip安装和使用 (Python)
  20. 使用NHibernate 3.2实现Repository(ORuM)(三)NHibernate、Mapping、Mapping-By-Code

热门文章

  1. Linux系统安装Appach 2.4.6
  2. VMware虚拟机VMware Authorization Service不能启动问题
  3. PHP require和include的区别
  4. Android Button监听的方式
  5. 闲谈简单设计(KISS)疑惑
  6. jQuery获取及设置单选框,多选框,文本框内容
  7. 如何在Chrome中保存您当前的所有标签,以便以后阅读
  8. JavaScript 使用random()生成随机数
  9. 配置本地及网络yum源(详细步骤)
  10. Vue 组件实例属性的使用