前言
好久沒有寫微博了,因?yàn)榍岸螘r(shí)間由于家庭原因決定從工作了3年多的北京轉(zhuǎn)移到上海去。依賴注入在學(xué)習(xí)net core的時(shí)候也有寫過類似的東西,只是實(shí)踐的較少,結(jié)果來到上海新公司系統(tǒng)框架涉及到了這塊知識(shí)點(diǎn),所以在了解完自己的項(xiàng)目之后決定做一些相關(guān)的總結(jié)。接下來就讓我們先來了解hewi依賴注入。
什么是依賴注入
依賴注入,全稱是“依賴注入到容器”, 容器(IOC容器)是一個(gè)設(shè)計(jì)模式,它也是個(gè)對(duì)象,你把某個(gè)類(不管有多少依賴關(guān)系)放入這個(gè)容器中,可以“解析”出這個(gè)類的實(shí)例。所以依賴注入就是把有依賴關(guān)系的類放入容器(IOC容器)中,然后解析出這個(gè)類的實(shí)例。劃重點(diǎn):依賴注入是為了實(shí)現(xiàn)控制反轉(zhuǎn)的一種設(shè)計(jì)模式?!粳F(xiàn)在知道gof之外還有其他的設(shè)計(jì)模式了吧?!?/p>
為什么要用依賴注入
我們編程希望高內(nèi)聚低耦合,所以解耦是很多理論的出發(fā)點(diǎn),依賴注入控制反轉(zhuǎn)也是為了解耦。那么冒昧問一下啊低耦合是什么?我的理解就是:我們?cè)诰幊踢^程中,我們不需要知道組件與類庫的內(nèi)容只需知道他們提供的接口,調(diào)用接口就能實(shí)現(xiàn)功能,我們就說這種情況是低耦合。
在沒有接觸到依賴注入的時(shí)候,解耦的思路其實(shí)也就是gof設(shè)計(jì)模式和設(shè)計(jì)原則。我以前分享的很多文章牽涉到的封裝類庫都是基于面向接口的方式。舉個(gè)例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public interface IOrder { //Product 產(chǎn)品對(duì)象 decimal ValueProducts( params Product[] products); } public class Order : IOrder { public decimal ValueProducts( params Product[] products) { return products.Sum(p => p.Price*p.Number); } } |
以上是在做商城經(jīng)常寫的一個(gè)基類。比如我們以前商城中購物車下單就算其總價(jià)的方法調(diào)用的時(shí)候。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class ShoppingCart { //計(jì)算購物車內(nèi)商品總價(jià)錢 public decimal CalculateStockValue() { Product[] products = { new Product {Name = "龍牙2016新款" , Number=2,ModelNo = 121,ColorID=65,SizeID=78, Price = 289.40}, new Product {Name = "龍牙2017新款" , ModelNo = 121,ColorID=65,SizeID=78, Number=2,Price =3800}, }; IOrder order = new Order(); //計(jì)算商品總價(jià)錢 decimal totalValue = order.ValueProducts(products); return totalValue; } } |
以上是我常用的方式來處理自己的業(yè)務(wù)需求的。這種面向接口的方式,如果我們要計(jì)算金額的方式改變了,比如我們尺寸32的金額打7折,那么只需增加金額的類。改變接口實(shí)例化即可。代碼就不敲了應(yīng)該都懂吧(低耦合)。那么我們可以看出ShoppingCart是依賴于接口與實(shí)現(xiàn)的對(duì)不對(duì),那么現(xiàn)在我們考慮一個(gè)問題,購物車雖然調(diào)用接口實(shí)例化,但是它也是要依賴于order的,那么減少它的依賴性有沒有辦法——就是把他們完全分開。那么這種問題的解決就用到了依賴注入了。劃重點(diǎn):依賴注入就是減少對(duì)接口實(shí)例化對(duì)象的依賴。那么怎么來實(shí)現(xiàn)依賴注入呢?
構(gòu)造注入的實(shí)現(xiàn)
通過類的構(gòu)造函數(shù)
第一次看net core別人也是講的這種方式,下面看一下代碼。設(shè)置一個(gè)服務(wù)類接口類型的數(shù)據(jù)成員,并以構(gòu)造函數(shù)為注入點(diǎn),這個(gè)構(gòu)造函數(shù)接受一個(gè)具體的服務(wù)類實(shí)例為參數(shù),并將它賦給服務(wù)類接口類型的數(shù)據(jù)成員。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class ShoppingCart { IOrder order; //構(gòu)造函數(shù),參數(shù)為實(shí)現(xiàn)了IOrder 接口的類的實(shí)例 public ShoppingCart(IOrder _order) { order = _order; } //計(jì)算購物車內(nèi)商品總價(jià)錢 public decimal CalculateStockValue() { Product[] products = { new Product {Name = "龍牙2016新款" , Number=2,ModelNo = 121,ColorID=65,SizeID=78, Price = 289.40}, new Product {Name = "龍牙2017新款" , ModelNo = 121,ColorID=65,SizeID=78, Number=2,Price =3800}}; //計(jì)算商品總價(jià)錢 decimal totalValue = order.ValueProducts(products); return totalValue; } |
以上代碼最秒的地方就是ShoppingCart與接口IOrder的實(shí)現(xiàn)order完全沒有關(guān)系,不需要了解他是怎么實(shí)現(xiàn)的。這就是依賴注入。這種叫做構(gòu)造注入。
在我們討論下一種注入的方式的時(shí)候,有個(gè)問題其實(shí)還沒有解決。“依賴是如何產(chǎn)生的?”把依賴當(dāng)作構(gòu)造函數(shù)參數(shù)來寫,盡管使用這可以手動(dòng)提供這種依賴,但是當(dāng)整個(gè)系統(tǒng)都依賴注入,那就意味著任何一個(gè)組件我們都需要知如道滿足每一部分的需求(服務(wù)定位器),是不是很頭大?那么這時(shí)我們就要要引入一個(gè)概念的“容器”-----依賴注入容器。
1
2
3
4
5
|
protected override void RegisterBuilder(ContainerBuilderWrapper builder) { base .RegisterBuilder(builder); //注入倉儲(chǔ) builder.RegisterType<Order>().As<IOrder>(); } |
以上為mvc容器的一種實(shí)現(xiàn)。AS 后邊是服務(wù)類繼承的接口,其實(shí)我對(duì)它的理解就是:如果有人請(qǐng)求這種類型。我們就給他這個(gè)類型的對(duì)象。
屬性注入
其實(shí)依賴注入spring相關(guān)的資料應(yīng)該有很多,所以很多知識(shí)點(diǎn)也是通過java那的理論借鑒過來的。屬性注入我確實(shí)看的net的書了解的。
如果需要使用到被依賴對(duì)象的某個(gè)屬性,在被依賴對(duì)象被創(chuàng)建之后,IoC容器會(huì)自動(dòng)初始化該屬性
首先還是定一個(gè)接口
1
2
3
4
5
6
7
|
public interface Iorder { { //Product 產(chǎn)品對(duì)象 decimal ValueProducts( params Product[] products); } } |
屬性注入如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class ShoppingCart { private iordre _order; public iordre Order { get { return _order; } set { _order = value; } } public decimal ValueProducts( params Product[] products) { return Order.ValueProducts(products); } } |
Setter注入
設(shè)置一個(gè)服務(wù)類接口類型的數(shù)據(jù)成員,并設(shè)置一個(gè)Set方法作為注入點(diǎn),這個(gè)Set方法接受一個(gè)具體的服務(wù)類實(shí)例為參數(shù),并將它賦給服務(wù)類接口類型的數(shù)據(jù)成員。其實(shí)這種是注入方式較為靈活使用者也較多。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
//服務(wù)接口 internal interface IServiceClass { String ServiceInfo(); } //服務(wù)方法 internal class ServiceClassA : IServiceClass { public String ServiceInfo() { return "我是ServceClassA" ; } } //服務(wù)方法 internal class ServiceClassB : IServiceClass { public String ServiceInfo() { return "我是ServceClassB" ; } } //客戶類實(shí)現(xiàn)set internal class ClientClass { private IServiceClass _serviceImpl; public void Set_ServiceImpl(IServiceClass serviceImpl) { this ._serviceImpl = serviceImpl; } public void ShowInfo() { Console.WriteLine(_serviceImpl.ServiceInfo()); } } //調(diào)用 class Program { static void Main( string [] args) { IServiceClass serviceA = new ServiceClassA(); IServiceClass serviceB = new ServiceClassB(); ClientClass client = new ClientClass(); client.Set_ServiceImpl(serviceA); client.ShowInfo(); client.Set_ServiceImpl(serviceB); client.ShowInfo(); } } |
結(jié)束語
其實(shí)依賴注入可聊的有很多,net core的出現(xiàn)依賴注入是必不可少的一個(gè)知識(shí)點(diǎn)。后面可聊的比如依賴注入與反射,依賴注入與多態(tài),依賴注入的框架。。。。。。。
好久不寫博客,準(zhǔn)備的也不夠充分。有興趣的小伙伴就去網(wǎng)上找去吧。
.net書的話:
《asp net mvc5 高級(jí)編程》《Dependency Injection in .NET 》(沒有中文)
java相關(guān)的書應(yīng)該會(huì)多一些。有興趣的就一起學(xué)習(xí)一下吧。
以上就是詳解asp.net core 依賴注入的詳細(xì)內(nèi)容,更多關(guān)于asp.net core 依賴注入的資料請(qǐng)關(guān)注服務(wù)器之家其它相關(guān)文章!
原文鏈接:https://www.cnblogs.com/wyl1924/p/7795445.html