一、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