spring5 源码 ioc_IOC框架--AutoFac - Linybo2008

一. 说在前面的话

  在框架搭建过程中,在层与层的解耦方面,势必会涉及到IOC框架,.Net 平台下我用过的IOC框架主要是: 、Unity、AutoFac,当然还有Castle(我没用过,就不发表任何评论了), 在用过的IOC框架中, 相对很老了,貌似在2015年就不在更新了,但基本的功能也够用了。 现阶段用的最多的就是Unity和AutoFac了,版本更新也比较快,Unity大约一年前写过两篇文章了,本次在该框架系列也会考虑更新一下Unity,本节主要介绍一下AutoFac的几个基本用法。

  先说一下两个概念IOC和DI,我的理解:

  ① IOC:调用者不再创建(不自己new)被调用者的实例,而是交给容器去创建(AutoFac就充当这里的容器),这就是控制反转。

  ② DI:容器创建好的实例再注入调用者的过程,就是依赖注入(比如:属性注入、构造函数注入等)。

AutoFac的信息:

  ① 官网地址:

  ② 官方文档: (英文)     (中文)

  ③ 最新版本: (截止2018-08-21)

  本节的内容主要包括:

    1. 在使用IOC框架之前的几种创建对象的方式。

    2. AutoFac的基本用法和几种生命周期。

    3. AutoFac和Asp.Net MVC5进行整合,利用属性的方式进行注入。

事先说明一下本节要用到的实现类和接口类:

(1). 层中包括:CatBLL、DogBLL、RoleBLL、UserBLL。

(2). 层包括:IAnimalBLL、IPeopleBLL、IRoleBLL、IUserBLL。

二. 引入IOC框架之前的几个写法

1. 最原始的方式直接new(需添加对BLL层的引用)

1{
2    UserBLL userBll = new UserBLL();
3var result1 = ();
4   Console.WriteLine(result1);
5 }

2. 面向接口编程(仍需添加对BLL层的引用)

1  {
2      IUserBLL userBll = new UserBLL();
3var result1 = ();
4     Console.WriteLine(result1);
5   }

3. 接口+反射(只需将BLL层的程序集拷贝进来)

4. 手写IOC(反射+简单工厂+配置文件)【需将BLL层的程序集拷贝进来】

 配置文件代码:

  <appSettings>
    <!--直接修改配置文件,可以切换IUserBLL的实现类,发布后可以直接通过改配置文件,代码什么也不用改,体会:反射+面向接口编程-->
    <add key="DllName" value=""/>
    <add key="ClassName" value=".UserBLL"/>
  </appSettings>

简单工厂代码:

调用代码:

1{
2       IUserBLL userBLL = ();
3var result = ();
4      Console.WriteLine(result);
5 }

三. AutoFac常见用法总结

1. 基本用法

   同时添加对层和层的引用,然后 声明容器→注册实例→解析对象→调用方法、进行测试,代码如下:

  评价:这种用法单纯的是为了介绍AutoFac中的几个方法,仅此而已,在实际开发没有这么用的,坑比用法,起不到任何解耦的作用。

2. AsImplementedInterfaces的用法

   在很多情况下,一个类可能实现了多个接口, 如果我们通过  ().As<IxxxBLL>(); 这种方式按部就班排着把这个类注册给每个接口,实现几个接口,就要写几行注册代码,很繁琐,我们可以通过 AsImplementedInterfaces()方法,可以把一个类注册给它实现的全部接口。

   这样的话,想用哪个接口,通过Resolve解析即可,代码如下:

  评价:同时添加对层和层的引用,这里也是单纯的为了介绍AsImplementedInterfaces()的用法,还是存在实现类的身影,在实际开发中没有这么用的,起不到任何解耦的作用,坑比用法。

3. AutoFac+反射(彻底消灭实现类)

  引入反射的背景:前面两种方式都需要添加对层的引用,麻烦的要死,根本没有什么改观,还是紧耦合在一起。并且如果有很多接口和实现类的话,用RegisterType一行一行的去写,累个半死,在这种情况下引入反射的概念,简化代码量,代码如下:

  评价:彻底摆脱了实现类的身影,与层进行了解耦,只需要添加对层的引用,但需要把的程序集拷贝到AutoFacTest项目下。

小小的升级一下:

   把反射那个程序集类写到配置文件中,然后在代码中通过读取配置文件进行进一步的反射,代码如下:

1<appSettings>2<add key="DllName" value=""/>3</appSettings>

4. PropertiesAutowired(属性的自动注入)

  背景:一个实现类中定义了其他类型的接口属性,比如RoleBLL中定义IUserBLL的接口属性,而且要对其进行调用, 这个时候就需要通过PropertiesAutowired实现属性的自动注入了。

  注:只有通过AutoFac创建的对象才能实现属性的自动注入!! 相关的类、接口要是public类型。

79345ce60d68f1a124d151f7d878f827.png

  下面测试一下不是AutoFac创建的对象能否实现属性的自动注入,新建TempTest类,在里面声明IUserBLL属性,并且在方法中进行调用,然后new一个TempTest对象,对该showMsg方法进行调用,发现报空指针错误,说明userBLL属性为空,没能自动注入。

1//测试自己new的对象不能实现属性的自动注入
2//下面代码报空指针错误3{
4      TempTest t = new TempTest();
5     t.showMsg();
6 }

5. 1个接口多个实现类的情况

  背景:1个接口有多个实现类的情况(DogBLL 和 CatBLL 都实现了 IAnimalBLL接口)

  分析:();只会返回其中一个类的对象

  解决方案:如果想返回多个实现类的对象,改成 ()即可。

6. AutoFac的几种常见生命周期

1. InstancePerDependency:每次请求 Resovle都返回一个新对象。InstancePerDependency()【这也是默认的创建实例的方式。】

2. SingleInstance: 单例,只有在第一次请求的时候创建 。SingleInstance()

3. InstancePerRequest:ASP.Net MVC 专用,每次http请求内一个对象(也可以理解为一个方法内)。InstancePerRequest() 和 CallContext神似

4. InstancePerLifetimeScope:在一个生命周期域中,每一个依赖或调用创建一个单一的共享的实例,且每一个不同的生命周期域,实例是唯一的,不共享的。

 下面测试一下前两种生命周期

 情况1

结果:False,证明InstancePerDependency 每次都创建一个新对象

情况2

结果:true,证明SingleInstance 每次都返回同一个对象。

四. AutoFac与MVC整合

1. Controller中通过属性注入对象

 步骤1:在层中添加对层的引用,并将的程序集拷贝到 中,或者直接改一下输出路径。

 步骤2:通过Nuget安装程序集 。

 步骤3:在Gloabl 注册 AutoFac代码。

f899ca239a34fc023a47f4a88b099c68.png

PS:分享个小技巧

ad2400657ed4a71939795ba1f283362f.png

步骤4:在Controller中进行调用。

 ca52cb4dcabafbf219a5832617f120b4.png

2. 普通类中通过代码获取对象

  在一个没有通过AutoFac注册的普通类中如何获取接口对象呢,通过();来获取。

  代码如下:

3. 如何在普通类中通过属性的方式注入对象

需要有两个条件:

  ①: 这个普通类的创建必须在Global中通过AutoFac来进行注册。

  ②: 获取这个类的时候必须通过 (); 这种方式来获取。

 在Global文件中注册该普通类

 e7d8149ce765d4bb04eb44063bfbcad5.png

该普通类CommonHelp的获取必须通过();方式来获取。

 653bb5bc03c4447826dbc69e31d4ffb5.png

4. 在单独线程中获取对象

  比如在 中,需要通过下面代码来获取。

f5be8098bd13fdbe10c3ffb4729d2d73.png

详细代码如下:

*************转摘:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值