一、Autofac简介

Autofac和其他容器的不同之处是它和C#语言的结合非常紧密,在使用过程中对你的应用的侵入性几乎为零,更容易与第三方的组件集成。Autofac的主要特性如下:

  • 组件侵入性为零:组件不需要去引用Autofac。
  • 灵活的模块化系统:通过模块化组织你的程序,应用程序不用纠缠于复 杂的XML配置系统或者是配置参数。
  • 自动装配:可以是用lambda表达式注册你的组件,autofac会根据需要选择构造函数或者属 性注入
  • XML配置文件的支持:XML配置文件过度使用时很丑陋,但是在发布的时候通常非常有用
  • 组件的多服务支持:许 多设计师喜欢使用细粒度的接口来控制依赖 , autofac允许一个组件提供多个服务

二、Autofac安装

1:使用Nuget下载 “Autofac”库,需注意,使用 .net framework必须在4.7以上版本,低于4.7版本的安装会失败。

三、Autofac的注册 —— 使用类型进行注册与使用

 1 using Autofac;
2 using System;
3
4 namespace BankOperation
5 {
6 class Program
7 {
8 static void Main(string[] args)
9 {
10 // 创建 ContainerBuilder
11 ContainerBuilder builder = new ContainerBuilder();
12
13 // 注册
14 builder.RegisterType<ABank>().As<IUnionPay>();
15
16 // 实例化
17 IContainer container = builder.Build();
18 var dev = container.Resolve<IUnionPay>();
19 dev.SaveMoneny(80);
20 dev.WithdrawMoney(50);
21
22 Console.ReadKey();
23 }
24
25 }
26
27 public interface IUnionPay
28 {
29 /// <summary>
30 /// 存钱
31 /// </summary>
32 /// <param name="amount">存钱金额</param>
33 void SaveMoneny(int amount);
34
35 /// <summary>
36 /// 取钱
37 /// </summary>
38 /// <param name="amount">取钱金额</param>
39 void WithdrawMoney(int amount);
40 }
41
42 public class ABank:IUnionPay
43 {
44 public void SaveMoneny(int amount)
45 {
46 Console.WriteLine($"把钱存入A银行,金额为:{amount}");
47 }
48
49 public void WithdrawMoney(int amount)
50 {
51 Console.WriteLine($"从A银行取钱,金额为:{amount}");
52 }
53 }
54 }

四、Autofac的注册 —— 使用别名进行注册与使用(一个接口有多个实现类时)

 1 using Autofac;
2 using System;
3
4 namespace BankOperation
5 {
6 class Program
7 {
8 static void Main(string[] args)
9 {
10 Console.Write("请输入银行名称:");
11 string name = Console.ReadLine();
12 Operation(name);
13
14 Console.ReadKey();
15 }
16
17 static void Operation(string name)
18 {
19 // 创建 ContainerBuilder
20 ContainerBuilder builder = new ContainerBuilder();
21
22 // 使用别名进行注册
23 builder.RegisterType<ABank>().Named<IUnionPay>("A");
24 builder.RegisterType<BBank>().Named<IUnionPay>("B");
25
26 // 使用别名进行实例化
27 IContainer container = builder.Build();
28 var dev = container.ResolveNamed<IUnionPay>(name);
29 dev.SaveMoneny(80);
30 dev.WithdrawMoney(50);
31 }
32 }
33
34 public interface IUnionPay
35 {
36 /// <summary>
37 /// 存钱
38 /// </summary>
39 /// <param name="amount">存钱金额</param>
40 void SaveMoneny(int amount);
41
42 /// <summary>
43 /// 取钱
44 /// </summary>
45 /// <param name="amount">取钱金额</param>
46 void WithdrawMoney(int amount);
47 }
48
49 public class ABank:IUnionPay
50 {
51 public void SaveMoneny(int amount)
52 {
53 Console.WriteLine($"把钱存入A银行,金额为:{amount}");
54 }
55
56 public void WithdrawMoney(int amount)
57 {
58 Console.WriteLine($"从A银行取钱,金额为:{amount}");
59 }
60 }
61
62 public class BBank : IUnionPay
63 {
64 public void SaveMoneny(int amount)
65 {
66 Console.WriteLine($"把钱存入B银行,金额为:{amount}");
67 }
68
69 public void WithdrawMoney(int amount)
70 {
71 Console.WriteLine($"从B银行取钱,金额为:{amount}");
72 }
73 }
74 }

五、Autofac的注册 —— 使用Lambda进行注册与使用(传递参数时)

反射在组件创建时是个很好的选择. 但是, 当组件创建不再是简单的调用构造方法时, 事情将变得混乱起来。可通过Lambda表达式传递一个实例,通过实例的初始化函数和公共属性传递需要注入的信息:

 1 using Autofac;
2 using System;
3
4 namespace BankOperation
5 {
6 class Program
7 {
8 static void Main(string[] args)
9 {
10 // 创建 ContainerBuilder
11 ContainerBuilder builder = new ContainerBuilder();
12
13 // 注册(通过实例化函数传递参数+类的公共属性)
14 builder.Register<IUnionPay>(c => new ABank("测试A银行"){ BankRate =8.12});
15
16 // 实例化
17 IContainer container = builder.Build();
18 var dev = container.Resolve<IUnionPay>();
19 dev.SaveMoneny(80);
20 dev.WithdrawMoney(50);
21
22 Console.ReadKey();
23 }
24
25 }
26
27 public interface IUnionPay
28 {
29 /// <summary>
30 /// 存钱
31 /// </summary>
32 /// <param name="amount">存钱金额</param>
33 void SaveMoneny(int amount);
34
35 /// <summary>
36 /// 取钱
37 /// </summary>
38 /// <param name="amount">取钱金额</param>
39 void WithdrawMoney(int amount);
40 }
41
42 public class ABank:IUnionPay
43 {
44 /// <summary>
45 /// 银行利率
46 /// </summary>
47 public double BankRate { get; set; }
48 public ABank(string name)
49 {
50 Console.WriteLine($"银行名称:{name}");
51 }
52 public void SaveMoneny(int amount)
53 {
54 Console.WriteLine($"把钱存入A银行(利率:{BankRate}%),金额为:{amount}");
55 }
56
57 public void WithdrawMoney(int amount)
58 {
59 Console.WriteLine($"从A银行取钱,金额为:{amount}");
60 }
61 }
62 }

当接口类有多个实现类,实现方式如下:

 1 using Autofac;
2 using System;
3
4 namespace BankOperation
5 {
6 class Program
7 {
8 static void Main(string[] args)
9 {
10 Console.Write("请输入银行名称:");
11 string name = Console.ReadLine();
12 Operation(name);
13
14 Console.ReadKey();
15 }
16
17 static void Operation(string name)
18 {
19 // 创建 ContainerBuilder
20 ContainerBuilder builder = new ContainerBuilder();
21
22 // 注册(通过实例化函数传递参数+类的公共属性)
23 builder.Register(c => new ABank("测试A银行") { BankRate = 8.12 }).Named<IUnionPay>("A");
24 builder.Register(c => new ABank("测试B银行") { BankRate = 10.25 }).Named<IUnionPay>("B");
25
26 // 实例化
27 IContainer container = builder.Build();
28 var dev = container.ResolveNamed<IUnionPay>(name);
29 dev.SaveMoneny(80);
30 dev.WithdrawMoney(50);
31 }
32
33 }
34
35 public interface IUnionPay
36 {
37 /// <summary>
38 /// 存钱
39 /// </summary>
40 /// <param name="amount">存钱金额</param>
41 void SaveMoneny(int amount);
42
43 /// <summary>
44 /// 取钱
45 /// </summary>
46 /// <param name="amount">取钱金额</param>
47 void WithdrawMoney(int amount);
48 }
49
50 public class ABank:IUnionPay
51 {
52 /// <summary>
53 /// 银行利率
54 /// </summary>
55 public double BankRate { get; set; }
56 public ABank(string name)
57 {
58 Console.WriteLine($"银行名称:{name}");
59 }
60 public void SaveMoneny(int amount)
61 {
62 Console.WriteLine($"把钱存入A银行(利率:{BankRate}%),金额为:{amount}");
63 }
64
65 public void WithdrawMoney(int amount)
66 {
67 Console.WriteLine($"从A银行取钱,金额为:{amount}");
68 }
69 }
70
71 public class BBank : IUnionPay
72 {
73 /// <summary>
74 /// 银行利率
75 /// </summary>
76 public double BankRate { get; set; }
77 public BBank(string name)
78 {
79 Console.WriteLine($"银行名称:{name}");
80 }
81 public void SaveMoneny(int amount)
82 {
83 Console.WriteLine($"把钱存入B银行(利率:{BankRate}%),金额为:{amount}");
84 }
85
86 public void WithdrawMoney(int amount)
87 {
88 Console.WriteLine($"从B银行取钱,金额为:{amount}");
89 }
90 }
91 }

四、程序集注册

以上方法全部都要进行手动注册,如果有很多接口及实现类,这种一一注册的方式很麻烦,我们可以一次性全部注册,当然也可以加筛选条件。

 1 using Autofac;
2 using System;
3 using System.Collections.Generic;
4 using System.Reflection;
5
6 namespace BankOperation
7 {
8 class Program
9 {
10 static void Main(string[] args)
11 {
12 Operation();
13
14 Console.ReadKey();
15 }
16
17 static void Operation()
18 {
19 // 创建 ContainerBuilder
20 ContainerBuilder builder = new ContainerBuilder();
21
22 //实现类所在的程序集名称
23 Assembly assembly = Assembly.Load("BankOperation");
24
25 // 获取程序集所在的全部实现类
26 builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces();
27
28 // t.Name.StartsWith:通过类名添加筛选条件,从类名的起始位开始匹配
29 builder.RegisterAssemblyTypes(assembly).Where(t => t.Name.StartsWith("B")).AsImplementedInterfaces();
30
31 // 实例化
32 IContainer container = builder.Build();
33 IEnumerable<IUnionPay> banks = container.Resolve<IEnumerable<IUnionPay>>();
34
35 foreach (var item in banks)
36 {
37 item.SaveMoneny(100);
38 item.WithdrawMoney(20);
39 Console.WriteLine("-----------------------------------------------");
40 }
41 }
42
43 }
44
45 public interface IUnionPay
46 {
47 /// <summary>
48 /// 存钱
49 /// </summary>
50 /// <param name="amount">存钱金额</param>
51 void SaveMoneny(int amount);
52
53 /// <summary>
54 /// 取钱
55 /// </summary>
56 /// <param name="amount">取钱金额</param>
57 void WithdrawMoney(int amount);
58 }
59
60 public class ABank:IUnionPay
61 {
62 public void SaveMoneny(int amount)
63 {
64 Console.WriteLine($"把钱存入A银行,金额为:{amount}");
65 }
66
67 public void WithdrawMoney(int amount)
68 {
69 Console.WriteLine($"从A银行取钱,金额为:{amount}");
70 }
71 }
72
73 public class BBank : IUnionPay
74 {
75 public void SaveMoneny(int amount)
76 {
77 Console.WriteLine($"把钱存入B银行,金额为:{amount}");
78 }
79
80 public void WithdrawMoney(int amount)
81 {
82 Console.WriteLine($"从B银行取钱,金额为:{amount}");
83 }
84 }
85 }

五、引用地址

1:Autofac官网地址:https://autofaccn.readthedocs.io/zh/latest/

2:Autofac 测试用例代码:https://github.com/autofac/Autofac

3:相关博文:关于.NET中的控制反转(二)- 依赖注入之 MEF关于.NET中的控制反转(一)- 概念与定义

关于.NET中的控制反转(三)- 依赖注入之 Autofac的更多相关文章

  1. 轻松了解Spring中的控制反转和依赖注入(二)

    紧接上一篇文章<轻松了解Spring中的控制反转和依赖注入>讲解了SpringIOC和DI的基本概念,这篇文章我们模拟一下SpringIOC的工作机制,使我们更加深刻的理解其中的工作. 类 ...

  2. Spring中的控制反转和依赖注入

    Spring中的控制反转和依赖注入 原文链接:https://www.cnblogs.com/xxzhuang/p/5948902.html 我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达 ...

  3. 轻松了解Spring中的控制反转和依赖注入(一)

    我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达170平方米,重达30吨,到现如今的个人笔记本,事物更加轻量功能却更加丰富,这是事物发展过程中的一个趋势,在技术领域中同样也是如此,企业级Ja ...

  4. 在DoNetMVC中使用控制反转和依赖注入【DI】

    本次是在MVC5中使用Autofac 第一步:程序包管理器控制台 Install-Package Autofac.MVC5 引入nuget包 这样成功之后,会在引用中出现两个DLL,分别是Autofa ...

  5. .Net Core MVC 网站开发(Ninesky) 2.3、项目架构调整-控制反转和依赖注入的使用

    再次调整项目架构是因为和群友dezhou的一次聊天,我原来的想法是项目尽量做简单点别搞太复杂了,仅使用了DbContext的注入,其他的也没有写接口耦合度很高.和dezhou聊过之后我仔细考虑了一下, ...

  6. Java 控制反转和依赖注入模式【翻译】【整理】

    Inversion of Control Containers and the Dependency Injection pattern --Martin Fowler 本文内容 Component ...

  7. spring 控制反转与依赖注入原理-学习笔记

    在Spring中有两个非常重要的概念,控制反转和依赖注入:控制反转将依赖对象的创建和管理交由Spring容器,而依赖注入则是在控制反转的基础上将Spring容器管理的依赖对象注入到应用之中: 所谓依赖 ...

  8. spring(3)------控制反转(IOC)/依赖注入(DI)

    一.spring核心概念理解 控制反转: 控制反转即IoC (Inversion of Control).它把传统上由程序代码直接操控的对象的调用权交给容器.通过容器来实现对象组件的装配和管理. 所谓 ...

  9. .NET Core ASP.NET Core Basic 1-2 控制反转与依赖注入

    .NET Core ASP.NET Core Basic 1-2 本节内容为控制反转与依赖注入 简介 控制反转IOC 这个内容事实上在我们的C#高级篇就已经有所讲解,控制反转是一种设计模式,你可以这样 ...

  10. (转)Ioc控制反转和依赖注入

    转载地址:https://zhuanlan.zhihu.com/p/95869440 控制反转控制反转(Inversion of Control,简称IoC),是面向对象编程中的一种设计思想,其作用是 ...

随机推荐

  1. 抖音数据采集SDK

    接口参数.返回示例请参考文档:抖音api Github仓库:DouyinSDK 0. 初始化 from douyin import AwemeSDK token = 'xxxxxxxx' host = ...

  2. redis 常用基本命令

    redis 常用基本命令 redis-cli 启动set  键  值       # 存储 单条数据  # set 'zsj' 'bab' get  键        # 通过键获取值   # get ...

  3. JavaSE15-集合·其二

    1.Set集合 1.1 Set集合概述和特点 Set集合的特点 元素存取无序 没有索引.只能通过迭代器或增强for循环遍历 不能存储重复元素 1.2 哈希值 哈希值简介 是JDK根据对象的地址或者字符 ...

  4. WindowsPhone8中LongListSelector的扩展解决其不能绑定SelectdeItem的问题

    微软在Wp8中集成了LongListSelector, 但是该控件在ViewModel中不能实现的SelectdeItem双向绑定,因为其不是DependencyProperty没办法只能实现扩展! ...

  5. html 09-HTML5详解(三)

    09-HTML5详解(三) #Web 存储 随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,传统方式我们以document. ...

  6. global和nonlocal之间的区别

    在局部修全局的:global 在局部修改嵌套的:nonlocal nonlocal代码示范 # 在局部作用域内去修改嵌套作用域内的变量# 当我们在局部作用域内要修改嵌套作用域内的变量时,需要使用non ...

  7. matplotlib的学习9-bar柱状图

    import matplotlib.pyplot as plt import numpy as np ''' 向上向下分别生成12个数据,X为 0 到 11 的整数 ,Y是相应的均匀分布的随机数据. ...

  8. 30道 有趣的 的 JVM 面试题

    目录 1.JVN内存结构 2.对象分配规则 3.解释内存中的栈(stack).堆(heap)和静态区(static area)的用法 4.Perm Space中保存什么数据?会引起OutOfMemor ...

  9. 5. 穿过拥挤的人潮,Spring已为你制作好高级赛道

    目录 ✍前言 版本约定 ✍正文 默认转换器注册情况 StreamConverter 代码示例 使用场景 兜底转换器 ObjectToObjectConverter part1:快速返回流程 part2 ...

  10. python菜鸟教程学习:数据结构

    列表方法 list.append(x):把一个元素添加到列表的结尾,相当于 a[len(a):] = [x]. list.extend(L):通过添加指定列表的所有元素来扩充列表,相当于 a[len( ...