網(wǎng)站首頁 編程語言 正文
1.前言
面向?qū)ο笤O(shè)計(jì)(OOD)里有一個(gè)重要的思想就是依賴倒置原則(DIP),并由該原則牽引出依賴注入(DI)、控制反轉(zhuǎn)(IOC)及其容器等老生常談的概念,初學(xué)者很容易被這些概念搞暈(包括我在內(nèi)),在學(xué)習(xí)Core依賴注入服務(wù)之前,下面讓我們先了解下依賴倒置原則(DIP)、依賴注入(DI)、控制反轉(zhuǎn)(IOC)等概念,然后再深入學(xué)習(xí)Core依賴注入服務(wù)。
2.依賴倒置原則(DIP)
高層模塊不依賴于低層模塊的實(shí)現(xiàn),而低層模塊依賴于高層模塊定義的接口。通俗來講,就是高層模塊定義接口,低層模塊負(fù)責(zé)實(shí)現(xiàn)。
2.依賴注入(DI)
2.1依賴(D)
當(dāng)一個(gè)類需要另一個(gè)類協(xié)作來完成工作的時(shí)候就產(chǎn)生了依賴。
示例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模塊輸出消息必須要實(shí)例化MyDependency模塊,也就是說IndexModel模塊業(yè)務(wù)的實(shí)現(xiàn)必須依賴于MyDependency模塊,這就是依賴。
2.2 注入(I)
根據(jù)DIP設(shè)計(jì)原則:高層模塊不依賴于低層模塊的實(shí)現(xiàn),而低層模塊依賴于高層模塊定義的接口,所以我們在這里定義一個(gè)接口供高層模塊調(diào)用,底層模塊負(fù)責(zé)實(shí)現(xiàn)。
示例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."); } }
從上述代碼可以看到當(dāng)我們調(diào)用IndexModel模塊OnGetAsync方法的時(shí)候,是通過IMyDependency接口實(shí)例化MyDependency類去實(shí)現(xiàn)其方法內(nèi)容的,這叫控制正轉(zhuǎn)。但是Master說,我們不應(yīng)該創(chuàng)建MyDependency類,而是讓調(diào)用者給你傳遞,于是你通過構(gòu)造函數(shù)讓外界把這兩個(gè)依賴給你。
示例3:
public interface IMyDependency { Task WriteMessage(string message); } public class MyDependency : IMyDependency { private readonly ILogger_logger; public MyDependency(ILogger 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."); } }
從上述代碼可以看到把依賴的創(chuàng)建丟給第三方系統(tǒng)(例:Autofac,Unity容器),也叫控制反轉(zhuǎn)(IOC)容器。自己只負(fù)責(zé)使用,其它人丟給你依賴的這個(gè)過程理解為注入。也叫控制反轉(zhuǎn)(IOC)。注意,框架內(nèi)部ILogger接口已注入,無需手動(dòng)再重新注入。
2.3 IOC容器
IOC容器可以看作是負(fù)責(zé)統(tǒng)一管理依賴關(guān)系的地方。常見有Autofac,Unity。
容器只要負(fù)責(zé)兩件事情:
●綁定服務(wù)與實(shí)例之間的關(guān)系
●獲取實(shí)例,并對實(shí)例進(jìn)行管理(創(chuàng)建與銷毀)
3.依賴倒置原則(DIP)與控制反轉(zhuǎn)(IOC)的區(qū)別
DIP是一種軟件設(shè)計(jì)原則,它僅僅告訴你高低層模塊之間應(yīng)該如何依賴,但是它并沒有告訴我們?nèi)绾谓獬嗷ヒ蕾嚹K的耦合。而IOC則是一種軟件設(shè)計(jì)模式,它告訴我們該如何解除模塊的耦合,它為相互依賴的組件提供抽象,將依賴(低層模塊)對象的獲得交給第三方系統(tǒng)(例:Autofac,Unity容器)來控制,即依賴對象不在被依賴模塊的類中直接通過new來獲取。
4.NET Core依賴注入(DI)服務(wù)
經(jīng)過上面描述,大家應(yīng)該應(yīng)該對依賴倒置原則(DIP)、依賴注入(DI)、控制反轉(zhuǎn)(IOC)這幾個(gè)概念有一定了解對吧。在.NET Core中DI的核心分為兩個(gè)組件:IServiceCollection和 IServiceProvider。
- IServiceCollection負(fù)責(zé)注冊
- IServiceProvider負(fù)責(zé)提供實(shí)例
下面讓我們來學(xué)習(xí)下NET Core是怎么依賴注入(DI)服務(wù)。
第一步:使用接口來實(shí)現(xiàn)依賴反轉(zhuǎn)。定義 IMyDependency 服務(wù)。
public interface IMyDependency { Task WriteMessage(string message); }
第二步:定義IMyDependency 服務(wù)的實(shí)現(xiàn)類MyDependency。
public class MyDependency : IMyDependency { private readonly ILogger_logger; public MyDependency(ILogger logger) { _logger = logger; } public Task WriteMessage(string message) { _logger.LogInformation( "MyDependency.WriteMessage called. Message: {MESSAGE}", message); return Task.FromResult(0); } }
第三步:把IMyDependency 服務(wù)注冊到服務(wù)容器中。
public void ConfigureServices(IServiceCollection services) { //注冊將服務(wù)生命期的范圍限定為單個(gè)請求的生命期,下節(jié)再來聊服務(wù)生命期 services.AddScoped(); }
第四步:把服務(wù)注入到使用它的類的構(gòu)造函數(shù)中。在HomeController里面調(diào)用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日志消息如下:
5.默認(rèn)服務(wù)容器替換
下面我們將來演示內(nèi)置容器怎么替換為其他容器示例,比如替換第三方 Autofac容器,我們需要在Startup.ConfigureServices方法里面注冊Autofac容器,具體代碼如下:
public IServiceProvider ConfigureServices(IServiceCollection services) { // Add Autofac var containerBuilder = new ContainerBuilder(); containerBuilder.RegisterModule(); containerBuilder.Populate(services); var container = containerBuilder.Build(); return new AutofacServiceProvider(container); }
這里需要注意的是如果需要使用第三方容器,Startup.ConfigureServices 必須返回 IServiceProvider。然后自定義一個(gè)模塊類配置依賴關(guān)系,具體代碼如下:
public class DefaultModule : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterType().As (); } }
應(yīng)用程序在運(yùn)行時(shí),使用 Autofac 來解析類型,并注入依賴關(guān)系。
原文鏈接:https://www.cnblogs.com/wzk153/p/10892444.html
相關(guān)推薦
- 2022-05-01 Python數(shù)據(jù)類型轉(zhuǎn)換匯總_python
- 2022-06-13 正則化DropPath/drop_path用法示例(Python實(shí)現(xiàn))_python
- 2023-06-18 Docker之實(shí)現(xiàn)掛載的三種方式匯總_docker
- 2022-02-23 MAC清除所有的mobileprovision
- 2022-11-12 asp.net?web?api2設(shè)置默認(rèn)啟動(dòng)登錄頁面的方法_實(shí)用技巧
- 2022-12-06 React深入分析useEffect源碼_React
- 2022-10-15 conda虛擬環(huán)境使用pip下載包到當(dāng)前環(huán)境的兩種方法_python
- 2022-08-25 C語言超詳細(xì)講解線性表_C 語言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支