<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
物件導向設計(OOD)裡有一個重要的思想就是依賴倒置原則(DIP),並由該原則牽引出依賴注入(DI)、控制反轉(IOC)及其容器等老生常談的概念,初學者很容易被這些概念搞暈(包括我在內),在學習Core依賴注入服務之前,下面讓我們先了解下依賴倒置原則(DIP)、依賴注入(DI)、控制反轉(IOC)等概念,然後再深入學習Core依賴注入服務。
高層模組不依賴於低層模組的實現,而低層模組依賴於高層模組定義的介面。通俗來講,就是高層模組定義介面,低層模組負責實現。
當一個類需要另一個類共同作業來完成工作的時候就產生了依賴。
範例1:
public class MyDependency { public MyDependency() { } public Task WriteMessage(string message) { Console.WriteLine($"MyDependency.WriteMessage called. Message: {message}"); return Task.FromResult(0); } } public class IndexModel : PageModel { MyDependency _dependency = new MyDependency(); public void OnGet() { _dependency.WriteMessage("IndexModel.OnGet created this message."); } }
由上述程式碼可以看到IndexModel模組輸出訊息必須要範例化MyDependency模組,也就是說IndexModel模組業務的實現必須依賴於MyDependency模組,這就是依賴。
根據DIP設計原則:高層模組不依賴於低層模組的實現,而低層模組依賴於高層模組定義的介面,所以我們在這裡定義一個介面供高層模組呼叫,底層模組負責實現。
範例2:
public interface IMyDependency { Task WriteMessage(string message); } public class MyDependency: IMyDependency { public MyDependency() { } public Task WriteMessage(string message) { Console.WriteLine($"MyDependency.WriteMessage called. Message: {message}"); return Task.FromResult(0); } } public class IndexModel : PageModel { IMyDependency _dependency = new MyDependency(); public void OnGet() { _dependency.WriteMessage("IndexModel.OnGet created this message."); } }
從上述程式碼可以看到當我們呼叫IndexModel模組OnGetAsync方法的時候,是通過IMyDependency介面範例化MyDependency類去實現其方法內容的,這叫控制正轉。但是Master說,我們不應該建立MyDependency類,而是讓呼叫者給你傳遞,於是你通過建構函式讓外界把這兩個依賴給你。
範例3:
public interface IMyDependency { Task WriteMessage(string message); } public class MyDependency : IMyDependency { private readonly ILogger<MyDependency> _logger; public MyDependency(ILogger<MyDependency> logger) { _logger = logger; } public Task WriteMessage(string message) { _logger.LogInformation( "MyDependency.WriteMessage called. Message: {MESSAGE}", message); return Task.FromResult(0); } } public class IndexModel : PageModel { private readonly IMyDependency _dependency; public IndexModel(IMyDependency dependency) { _dependency = dependency; } public void OnGet() { _dependency.WriteMessage("IndexModel.OnGet created this message."); } }
從上述程式碼可以看到把依賴的建立丟給第三方系統(例:Autofac,Unity容器),也叫控制反轉(IOC)容器。自己只負責使用,其它人丟給你依賴的這個過程理解為注入。也叫控制反轉(IOC)。注意,框架內部ILogger介面已注入,無需手動再重新注入。
IOC容器可以看作是負責統一管理依賴關係的地方。常見有Autofac,Unity。
容器只要負責兩件事情:
●繫結服務與範例之間的關係
●獲取範例,並對範例進行管理(建立與銷燬)
DIP是一種軟體設計原則,它僅僅告訴你高低層模組之間應該如何依賴,但是它並沒有告訴我們如何解除相互依賴模組的耦合。而IOC則是一種軟體設計模式,它告訴我們該如何解除模組的耦合,它為相互依賴的元件提供抽象,將依賴(低層模組)物件的獲得交給第三方系統(例:Autofac,Unity容器)來控制,即依賴物件不在被依賴模組的類中直接通過new來獲取。
經過上面描述,大家應該應該對依賴倒置原則(DIP)、依賴注入(DI)、控制反轉(IOC)這幾個概念有一定了解對吧。在.NET Core中DI的核心分為兩個元件:IServiceCollection和 IServiceProvider。
下面讓我們來學習下NET Core是怎麼依賴注入(DI)服務。
第一步:使用介面來實現依賴反轉。定義 IMyDependency 服務。
public interface IMyDependency { Task WriteMessage(string message); }
第二步:定義IMyDependency 服務的實現類MyDependency。
public class MyDependency : IMyDependency { private readonly ILogger<MyDependency> _logger; public MyDependency(ILogger<MyDependency> logger) { _logger = logger; } public Task WriteMessage(string message) { _logger.LogInformation( "MyDependency.WriteMessage called. Message: {MESSAGE}", message); return Task.FromResult(0); } }
第三步:把IMyDependency 服務註冊到服務容器中。
public void ConfigureServices(IServiceCollection services) { //註冊將服務生命期的範圍限定為單個請求的生命期,下節再來聊服務生命期 services.AddScoped<IMyDependency, MyDependency>(); }
第四步:把服務注入到使用它的類別建構函式中。在HomeController裡面呼叫IndexModel.OnGet方法輸出WriteMessage訊息。
public class IndexModel : PageModel { private readonly IMyDependency _dependency; public IndexModel(IMyDependency dependency) { _dependency = dependency; } public void OnGet() { _dependency.WriteMessage("IndexModel.OnGet created this message."); } } private readonly IMyDependency _iMyDependency; public HomeController(IMyDependency iMyDependency) { _iMyDependency = iMyDependency; } public IActionResult Index() { IndexModel _IndexModel = new IndexModel(_iMyDependency); _IndexModel.OnGet(); return View(); }
WriteMessage紀錄檔訊息如下:
下面我們將來演示內建容器怎麼替換為其他容器範例,比如替換第三方 Autofac容器,我們需要在Startup.ConfigureServices方法裡面註冊Autofac容器,具體程式碼如下:
public IServiceProvider ConfigureServices(IServiceCollection services) { // Add Autofac var containerBuilder = new ContainerBuilder(); containerBuilder.RegisterModule<DefaultModule>(); containerBuilder.Populate(services); var container = containerBuilder.Build(); return new AutofacServiceProvider(container); }
這裡需要注意的是如果需要使用第三方容器,Startup.ConfigureServices 必須返回 IServiceProvider。然後自定義一個模組類設定依賴關係,具體程式碼如下:
public class DefaultModule : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterType<CharacterRepository>().As<ICharacterRepository>(); } }
應用程式在執行時,使用 Autofac 來解析型別,並注入依賴關係。
到此這篇關於ASP.NET Core依賴關係注入的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援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