<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
大部分應用程式都是這樣編寫的:編譯時依賴關係順著執行時執行的方向流動,從而生成一個直接依賴項關係圖。 也就是說,如果類 A 呼叫類 B 的方法,類 B 呼叫 C 類的方法,則在編譯時,類 A 將取決於類 B,而 B 類又取決於類 C
應用程式中的依賴關係方向應該是抽象的方向,而不是實現詳細資訊的方向。而這就是控制反轉的思想。
應用依賴關係反轉原則後,A 可以呼叫 B 實現的抽象上的方法,讓 A 可以在執行時呼叫 B,而 B 又在編譯時依賴於 A 控制的介面(因此,典型的編譯時依賴項發生反轉)。 執行時,程式執行的流程保持不變,但介面引入意味著可以輕鬆插入這些介面的不同實現。
上下不同的實現方式在於之前的依賴關係是A->B->C,控制反轉後A->B介面->C介面,然後具體的B,C實現又是B->B介面 的反轉依賴。這樣的好處就是A只依賴B介面而不是依賴實現,具體我們要實現什麼只需要按照業務需求進行編寫,並且可以隨時替換實現而不會影響A的實現,這種思想就是控制反轉。
如下是順序依賴:
public class A { //依賴具體類 public B b; public C c; public A(B _b, C _c) { b = _b; c = _c; } public void Listen() { b.SayHi(); c.SayBye(); } } public class B { public void SayHi() { Console.WriteLine("hi..."); } } public class C { public void SayBye() { Console.WriteLine("bye..."); } }
如下是控制反轉:
public class A { //依賴介面 public IB b; public IC c; public A(IB _b, IC _c) { b = _b; c = _c; } public void Listen() { b.SayHi(); c.SayBye(); } } public interface IB { public void SayHi(); } public interface IC { public void SayBye(); }
.NET 支援依賴關係注入 (DI) 軟體設計模式,這是一種在類及其依賴項之間實現控制反轉 (IoC) 的技術。
我們首先用程式碼來看什麼是DI,在.net提供的擴充套件包Microsoft.Extensions.DependencyInjection中來完成DI,nuget安裝。
然後我們實現介面B和介面C,實現我們可以說英語,也可以說漢語,我們在SayHi和SayBye中輸出漢語。
public class B : IB { public void SayHi() { Console.WriteLine("你好..."); } } public class C : IC { public void SayBye() { Console.WriteLine("再見..."); } }
然後在服務容器中註冊依賴關係。 .NET 提供了一個內建的服務容器 IServiceProvider。 服務通常在應用啟動時註冊,並追加到 IServiceCollection。 新增所有服務後,可以使用 BuildServiceProvider 建立服務容器,然後在容器中直接“要”物件而不用去管它如何範例化,並且DI具備傳染性
,假如B參照了D介面ID,那麼我們註冊B並在獲取B範例時,參照的D介面也會被範例化。
//IServiceCollection 服務 IServiceCollection services = new ServiceCollection(); //服務註冊 services.AddTransient<A>(); services.AddTransient<IB, B>(); services.AddTransient<IC, C>(); //建立服務容器 var serviceProvider = services.BuildServiceProvider(); //獲取服務 var a = serviceProvider.GetRequiredService<A>(); //使用 a.Listen(); Console.ReadKey();
這就是通過DI依賴注入的方式來實現IOC的思想,或許你會好奇為什麼我們不直接範例化A,然後在構造方法裡面傳進去就行了,也就不依賴DI實現了。但是程式結構更復雜些呢,比如上面提到的B又有D,D又有F呢,這樣在構造的時候不是一直要new很多物件,而且同一個介面的不同實現還要去找範例化處的程式碼進行修改。例如SayHI我想說英文呢?那麼我們就可以實現一個BB,然後在服務註冊的地方註冊BB就可以了。
public class BB : IB { public void SayHi() { Console.WriteLine("hello..."); } }
替換註冊BB services.AddTransient<IB, BB>()
,而不用去改任何邏輯。
在註冊服務的時候我使用的AddTransient
方法,表示註冊的服務是瞬態的,也就是每次請求都是重新建立範例。同時還提供其它註冊服務的方法。
服務有三種宣告週期:
瞬態
作用域
單例
服務是每次從服務容器進行請求時建立的。 這種生存期適合輕量級、 無狀態的服務。 用 AddTransient 註冊服務。在處理請求的應用中,在請求結束時會釋放暫時服務。
指定了作用域的生存期指明瞭每個使用者端請求(連線)建立一次服務。 向 AddScoped 註冊範圍內服務。在處理請求的應用中,在請求結束時會釋放有作用域的服務。
想asp.net 在處理一個請求的時候是一個作用域,同樣我們自己也可以定義作用域。使用serviceProvider.CreateScope()
建立作用域,在作用域釋放後物件將被釋放。
我們使用AddScoped新增物件,然後在作用域中取兩個A物件進行比較,可以看到是True
。
如果我們用AddTransient註冊A,即使在作用域內兩個物件比較也是不一樣的,結果為False
。
單例大家應該好理解,就是設計模式中的單例,使用AddSingleton 註冊,在首次請求它們時進行建立;或者在向容器直接提供實現範例時由開發人員進行建立。 很少用到此方法,因為可能是執行緒不安全的,如果服務中有狀態。
在Microsoft.Extensions.DependencyInjection中只能用建構函式注入,其它框架還提供屬性注入,比如autofac。至於原因不得而知,當然也看個人喜好。查了些資料說是建構函式注入更科學,在物件建立的瞬間物件的構造方法將服務範例化,避免邏輯問題。
以上就是.net程式開發IOC控制反轉和DI依賴注入詳解的詳細內容,更多關於.net 控制反轉依賴注入的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45