编程语言
首页 > 编程语言> > 把Autofac玩的和javaSpring一样6

把Autofac玩的和javaSpring一样6

作者:互联网

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

本项目的目的 降低玩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. 注册为指定类型


public class B
{

}

//这个构造方法就是将A6注册为B类型 
[Component(typeof(B))]
public class A6: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容器

image

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

image

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

image

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

image

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

image

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

image

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

image

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

image

另外

image

Autowired自动装配

Autowired有哪些属性

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

 

打在构造方法上 属性

image

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

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

image

延迟自动装配Lazy


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

标签:Autofac,javaSpring,Autowired,DI,class,一样,注册,类型,public
来源: https://blog.csdn.net/qq_45533926/article/details/114980618