亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

ASP.NET Core依賴注入系列教程之控制反轉(zhuǎn)(IoC)

 更新時(shí)間:2018年11月05日 09:29:28   作者:蔣金楠  
這篇文章主要給大家介紹了關(guān)于ASP.NET Core依賴注入系列教程之控制反轉(zhuǎn)(IoC)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

ASP.NET Core在啟動(dòng)以及后續(xù)針對(duì)每個(gè)請(qǐng)求的處理過(guò)程中的各個(gè)環(huán)節(jié)都需要相應(yīng)的組件提供相應(yīng)的服務(wù),為了方便對(duì)這些組件進(jìn)行定制,ASP.NET通過(guò)定義接口的方式對(duì)它們進(jìn)行了“標(biāo)準(zhǔn)化”,我們將這些標(biāo)準(zhǔn)化的組件稱為服務(wù),ASP.NET在內(nèi)部專門維護(hù)了一個(gè)DI容器來(lái)提供所需的服務(wù)。要了解這個(gè)DI容器以及現(xiàn)實(shí)其中的服務(wù)提供機(jī)制,我們先得知道什么是DI(Dependence Injection),而一旦我們提到DI,又不得不說(shuō)IoC(Inverse of Control)。

一、流程控制的反轉(zhuǎn)

我聽(tīng)到很多人將IoC說(shuō)成是一種“面向?qū)ο蟮脑O(shè)計(jì)模式”,但在我個(gè)人看來(lái)IoC不能算作一種“設(shè)計(jì)模式”,其自身也與“面向?qū)ο蟆睕](méi)有直接的關(guān)系。很多人之所以不能很準(zhǔn)確地理解IoC源于他們忽略了一個(gè)最根本的東西,那就是IoC這個(gè)短語(yǔ)。換句話說(shuō),很多人之所以對(duì)IoC產(chǎn)生了諸多誤解是因?yàn)樗麄兒雎粤薎oC的定義。

IoC的全名Inverse of Control,翻譯成中文就是“控制反轉(zhuǎn)”或者“控制倒置”??刂品崔D(zhuǎn)也好,控制倒置也罷,它體現(xiàn)的意思是控制權(quán)的轉(zhuǎn)移,即原來(lái)控制權(quán)在A手中,現(xiàn)在需要B來(lái)接管。那么具體對(duì)于軟件設(shè)計(jì)來(lái)說(shuō),IoC所謂的控制權(quán)的轉(zhuǎn)移具有怎樣的體現(xiàn)呢?要回答這個(gè)問(wèn)題,就需要先了解IoC的C(Control)究竟指的是怎樣一種控制,在我看來(lái)這里所謂的控制更多地體現(xiàn)為一種“流程的控制”。

我們通過(guò)一個(gè)具體事例來(lái)說(shuō)明傳統(tǒng)的設(shè)計(jì)在采用了IoC之后針對(duì)流程的控制是如何實(shí)現(xiàn)反轉(zhuǎn)的。比如說(shuō)我們現(xiàn)在設(shè)計(jì)一個(gè)針對(duì)Web的MVC類庫(kù),不妨將其命名為MvcLib。MvcLib提供了如下所示的API幫助我們完成整個(gè)HTTP請(qǐng)求流程中的主要任務(wù)。具體來(lái)說(shuō),ListenAndReceiveRequest方法啟動(dòng)一個(gè)監(jiān)聽(tīng)器綁定到指定的地址進(jìn)行請(qǐng)求的監(jiān)聽(tīng),接收到的請(qǐng)求通過(guò)一個(gè)Request對(duì)象返回。ActivateController方法根據(jù)接收到的請(qǐng)求解析并激活請(qǐng)求的目標(biāo)Controller。ExecuteContrller方法執(zhí)行激活的Controller并返回一個(gè)表示視圖的View對(duì)象。RenderView最終將View對(duì)象轉(zhuǎn)換成HTML并作為當(dāng)前請(qǐng)求響應(yīng)的內(nèi)容。

 public static class MvcLib
 {
 public static Request ListenAndReceiveRequest(Uri address);
 public static Controller ActivateController (Request request);
 public static View ExecuteContrller(Controller controller);
 public static void RenderView(View view);
 } 

現(xiàn)在我們?cè)谶@個(gè)MvcLib的基礎(chǔ)上創(chuàng)建一個(gè)真正的MVC應(yīng)用,那么除了按照MvcLib的規(guī)范自定義具體的Controller和View之外,我們還需要自行控制從請(qǐng)求的監(jiān)聽(tīng)與接收、Controller的激活與執(zhí)行以及View的最終呈現(xiàn)在內(nèi)的整個(gè)流程,這樣一個(gè)執(zhí)行流程反映在如下所示的代碼中。

 public class App
 {
 static void Main(string[] args)
 {
 Uri address = new Uri("http://localhost/mvcapp");
 while (true)
 {
 Request request = MvcLib.ListenAndReceiveRequest(address);
 Task.Run(()=> ProcessRequest(request));
 }
 }
 
 private static void ProcessRequest(Request request)
 {
 Controller controller = MvcLib.ActiveController(request);
 View view = MvcLib.ExecuteContrller(controller);
 MvcLib.RenderView(view);
 }
 }

這個(gè)例子體現(xiàn)了右如圖所示的流程控制方式,即我們?cè)O(shè)計(jì)的類庫(kù)(MvcLib)僅僅通過(guò)API的形式提供某種單一功能的實(shí)現(xiàn),作為類庫(kù)消費(fèi)者的應(yīng)用程序(App)則需要自行編排整個(gè)工作流程。如果從重用的角度來(lái)講,這里被重用的僅限于實(shí)現(xiàn)某個(gè)環(huán)節(jié)單一功能的代碼,編排整個(gè)工作流程的代碼并沒(méi)有得到重用。

當(dāng)我們構(gòu)建一個(gè)應(yīng)用的時(shí)候,我們不僅僅是需要一個(gè)能夠提供API的類庫(kù),實(shí)際上更理想的形式是直接在一個(gè)現(xiàn)有的框架上構(gòu)架我們的應(yīng)用。類庫(kù)(Library)和框架(Framework)的不同之處在于,前者往往只是提供實(shí)現(xiàn)某種單一功能的API,而后者則針對(duì)一個(gè)目標(biāo)任務(wù)對(duì)這些單一功能進(jìn)行編排形成一個(gè)完整的流程,這個(gè)流程在一個(gè)引擎的驅(qū)動(dòng)下被執(zhí)行。

在我們上面演示MvcLib來(lái)說(shuō),使用它的應(yīng)用程序需要自行控制整個(gè)HTTP請(qǐng)求的處理流程,實(shí)際上這是一個(gè)很“泛化”的工作流程,幾乎所有的MVC應(yīng)用均采用這樣的流程監(jiān)聽(tīng)、接收請(qǐng)求并最終對(duì)請(qǐng)求予以響應(yīng)。如果我們將這個(gè)流程實(shí)現(xiàn)在一個(gè)MVC框架之中,由它構(gòu)建的所有MVC應(yīng)用就可以直接使用這個(gè)請(qǐng)求處理流程,而并不需要自行重復(fù)實(shí)現(xiàn)它。

現(xiàn)在我們將MvcLib從類庫(kù)改造成一個(gè)框架,并姑且將其稱為MvcFrame。如左圖所示,MvcFrame的核心是一個(gè)被稱為MvcEngine的執(zhí)行引擎,它驅(qū)動(dòng)一個(gè)編排好的工作流對(duì)HTTP請(qǐng)求進(jìn)行一致性處理。如果我們利用MvcFrame構(gòu)建一個(gè)具體的MVC應(yīng)用,除了根據(jù)我們的業(yè)務(wù)需求定義相應(yīng)的Controller和View之外,我們只需要初始化這個(gè)引擎并直接啟動(dòng)它即可。如果你曾經(jīng)開(kāi)發(fā)過(guò)ASP.NET MVC應(yīng)用,你會(huì)發(fā)現(xiàn)ASP.NET MVC就是這么一個(gè)框架。

有了上面演示的這個(gè)例子作為鋪墊,我們應(yīng)該很容易理解IoC所謂的控制反轉(zhuǎn)了??偟膩?lái)說(shuō),IoC是我們?cè)O(shè)計(jì)框架所采用的設(shè)計(jì)思想,所謂的控制反轉(zhuǎn)即是按照如右圖所示的方式將原來(lái)實(shí)現(xiàn)在應(yīng)用程序流程控制轉(zhuǎn)移到框架中。被轉(zhuǎn)移的是一個(gè)泛化的可重用的處理流程,所以IoC符合軟件設(shè)計(jì)一個(gè)基本的原則,即重用性。

二、對(duì)流程的定制

我們采用IoC實(shí)現(xiàn)了流程控制從應(yīng)用程序向框架自身的反轉(zhuǎn),但是這個(gè)被反轉(zhuǎn)的僅僅是一個(gè)泛化的流程,任何一個(gè)具體的應(yīng)用都可能需要對(duì)組成該流程的某些環(huán)節(jié)進(jìn)行定制。如左圖所示,我們將一個(gè)泛化的工作流程(A=>B=>C)被定義在框架之中,建立在該框架的兩個(gè)應(yīng)用需要對(duì)組成這個(gè)流程的某些環(huán)節(jié)進(jìn)行定制。比如步驟A和C可以被App1重用,但是步驟B卻需要被定制(B1),App2則重用步驟A和B,但是需要按照自己的方式(C2)處理步驟C。

IoC將對(duì)流程的控制從應(yīng)用程序轉(zhuǎn)移到框架之中,框架利用一個(gè)引擎驅(qū)動(dòng)整個(gè)流程的執(zhí)行。換句話說(shuō),應(yīng)用程序無(wú)需關(guān)心該工作流程的細(xì)節(jié),它只需要啟動(dòng)這個(gè)引擎即可。但是這個(gè)引擎一旦被啟動(dòng),框架就會(huì)完全按照預(yù)先編排好的流程進(jìn)行工作,如果應(yīng)用程序希望整個(gè)流程按照自己希望的方式被執(zhí)行,針對(duì)流程的定制一般在發(fā)生在啟動(dòng)引擎之前。

一般來(lái)說(shuō),框架會(huì)以相應(yīng)的形式提供一系列的擴(kuò)展點(diǎn),應(yīng)用程序則通過(guò)定義擴(kuò)展的方式實(shí)現(xiàn)對(duì)流程某個(gè)環(huán)節(jié)的定制。在引擎被啟動(dòng)之前,應(yīng)用程序?qū)⑺璧臄U(kuò)展注冊(cè)到框架之中。一旦引擎被正常啟動(dòng),這些注冊(cè)的擴(kuò)展會(huì)自動(dòng)參與到整個(gè)流程的執(zhí)行過(guò)程中。

雖然應(yīng)用程序是框架引擎的啟動(dòng)著,但是一旦引擎被啟動(dòng)之后它就喪失了對(duì)流程的控制,應(yīng)用程序?qū)α鞒痰亩ㄖ撇皇窃趫?zhí)行過(guò)程中對(duì)框架的干預(yù)來(lái)完成的,而只需要在流程執(zhí)行之前就將定制的部分準(zhǔn)備好,框架自身在執(zhí)行過(guò)程中會(huì)智能地選擇它們。從這個(gè)意義上講,IoC對(duì)流程的定制遵循著這樣一個(gè)原則,即“Don't call us, we'll call you!”,它被稱為好萊塢原則。

綜上所述,IoC一方面通過(guò)流程控制從應(yīng)用程序向框架的反轉(zhuǎn)實(shí)現(xiàn)了針對(duì)流程自身的重用,另一方面采用“好萊塢原則”使得這個(gè)被重用的流程可能自由地被定制,這兩個(gè)因素實(shí)際上決定了框架自身的價(jià)值。重用讓框架不僅僅是為應(yīng)用程序提供實(shí)現(xiàn)單一功能的API,而是提供一整套可執(zhí)行的解決方案;可定制則使我們可以為不同的應(yīng)用程序?qū)蚣苓M(jìn)行定制,這無(wú)疑讓框架可以使用到更多的應(yīng)用之中。

三、 IoC模式

正如我們?cè)谏厦嫣岬竭^(guò)的,很多人將IoC理解為一種“面向?qū)ο蟮脑O(shè)計(jì)模式”,實(shí)際上IoC自身不僅與面向?qū)ο鬀](méi)有必然的聯(lián)系,它也算不上是一種設(shè)計(jì)模式。一般來(lái)講,設(shè)計(jì)模式提供了一種解決某種具體問(wèn)題的方案,但是IoC既沒(méi)有一個(gè)針對(duì)性的問(wèn)題領(lǐng)域,其自身沒(méi)有提供一種可實(shí)施的解決方案,所以我更加傾向于將IoC視為一種設(shè)計(jì)原則,實(shí)際上很多我們熟悉的設(shè)計(jì)模式背后采用了IoC原則。

模板方法(Template Method)

提到IoC,很多人首先想到的是DI,但是在我看來(lái)與IoC聯(lián)系得最為緊密的則是另一種被稱為“模板方法”的設(shè)計(jì)模式。模板方法模式與IoC的意圖可以說(shuō)完全一致,該模式主張將一個(gè)可復(fù)用的工作流程或者由多個(gè)步驟組成的算法定義成模板方法,組成這個(gè)流程或者算法的步驟則實(shí)現(xiàn)在相應(yīng)的虛方法之中,模板方法根據(jù)流程先后調(diào)用這些虛方法。所有這些方法均定義在同一個(gè)類中,我們可以通過(guò)派生該類并重寫(xiě)相應(yīng)的虛方法達(dá)到對(duì)流程定制的目的。

對(duì)于上面我們演示的這個(gè)MVC的例子,我們可以將整個(gè)請(qǐng)求處理流程實(shí)現(xiàn)在如下一個(gè)MvcEngine類中,請(qǐng)求的監(jiān)聽(tīng)與接收、目標(biāo)Controller的激活與執(zhí)行以及View的呈現(xiàn)則分別定義在四個(gè)受保護(hù)的虛方法中,模板方法Start根據(jù)預(yù)定義的請(qǐng)求處理流程先后調(diào)用這四個(gè)方法。

 public class MvcEngine
 {
 public void Start(Uri address)
 {
 while (true)
 {
 Request request = this.OnListenAndReceiveRequest(address);
 Task.Run(() =>
 {
  Controller controller = this.OnActivateController(request);
  View view = this.OnExecuteContrller(controller);
  this.OnRenderView(view);
 });
 }
 }
 protected virtual Request OnListenAndReceiveRequest(Uri address) ;
 protected virtual Controller OnActivateController(Request request) ;
 protected virtual View OnExecuteContrller(Controller controller) ; 
 protected virtual void OnRenderView(View view) ;
 }

對(duì)于具體的應(yīng)用來(lái)說(shuō),如果定義在MvcEngine針對(duì)請(qǐng)求的處理方式完全符合它的要求,它只需要?jiǎng)?chuàng)建這個(gè)一個(gè)MvcEngine對(duì)象,然后指定一個(gè)對(duì)應(yīng)的基地址調(diào)用模板方法Start開(kāi)啟這個(gè)MVC引擎即可。如果該MVC引擎處理請(qǐng)求的某個(gè)環(huán)節(jié)不能滿足它的要求,它可以創(chuàng)建MvcEngine的派生類,并重寫(xiě)實(shí)現(xiàn)該環(huán)節(jié)的相應(yīng)虛方法即可。比如說(shuō)定義在某個(gè)應(yīng)用程序中的Controller都是無(wú)狀態(tài)的,它希望采用單例(Singleton)的方式重用已經(jīng)激活的Controller以提高性能,那么它就可以按照如下的方式創(chuàng)建一個(gè)自定義的FoobarMvcEngine并按照自己的方式重寫(xiě)OnActivateController方法既可。

 public class FoobarMvcEngine : MvcEngine
 {
 protected override View OnExecuteContrller(Controller controller)
 {
 <<省略實(shí)現(xiàn)>>
 }
 }

模板方法如果結(jié)合“事件注冊(cè)”往往可以使應(yīng)用程序?qū)α鞒痰亩ㄖ谱兊酶幼杂?。如下面的代碼片段所示,我們?yōu)镃ontroller的激活與執(zhí)行以及View的呈現(xiàn)定義了六個(gè)事件,它們分別在這個(gè)三個(gè)環(huán)節(jié)開(kāi)始之前和結(jié)束之后被觸發(fā)。這么一個(gè)MvcEngine可以直接被使用,應(yīng)用程序只需要注冊(cè)相應(yīng)的事件完成對(duì)請(qǐng)求處理流程的定制。

 public class MvcEngine
 {
 //其他成員
 protected virtual Controller OnActivateController(Request request) ;
 protected virtual View OnExecuteContrller(Controller controller) ; 
 protected virtual void OnRenderView(View view) ;
 
 public EventHandler<ControllerActivationEventArgs> ControllerActivating;
 public EventHandler<ControllerActivationEventArgs> ControllerActivated;
 public EventHandler<ControllerExecutionEventArgs> ControllerExecuting;
 public EventHandler<ControllerExecutionEventArgs> ControllerExecuted;
 public EventHandler<ViewRenderEventArgs> ViewRendering;
 public EventHandler<ViewRenderEventArgs> ViewRendered;
 }

工廠方法(Factory Method)

對(duì)于一個(gè)復(fù)雜的流程來(lái)說(shuō),我們傾向于將組成該流程的各個(gè)環(huán)節(jié)實(shí)現(xiàn)在相應(yīng)獨(dú)立的組件之中,那么針對(duì)流程的定制就可以通過(guò)提供不同組件的形式來(lái)實(shí)現(xiàn)。我們知道23種設(shè)計(jì)模式之中有一種重要的類型,那就是“創(chuàng)建型模式”,比如常用的“工廠方法”和“抽象工廠”,那么IoC所體現(xiàn)的針對(duì)流程的共享與定制可以通過(guò)它們來(lái)完成。

所謂的工廠方法,說(shuō)白了就是在某個(gè)類中用于提供依賴對(duì)象的方法,這個(gè)方法可以是一個(gè)單純的虛方法,也可以是具有默認(rèn)實(shí)現(xiàn)的虛方法,至于方法聲明的返回類型,可以是一個(gè)接口或者抽象類,也可以是未被封閉(Sealed)的具體類型。作為它的派生類型,它可以實(shí)現(xiàn)或者重寫(xiě)工廠方法以提供所需的具體對(duì)象。

同樣以我們的MVC框架為例,我們讓獨(dú)立的對(duì)象來(lái)完成組成整個(gè)請(qǐng)求處理流程的四個(gè)核心環(huán)節(jié)。具體來(lái)說(shuō),我們分別定義了四個(gè)核心的類型(Listener、ControllerActivator、ControllerExecutor和ViewGenderer)來(lái)分別負(fù)責(zé)請(qǐng)求監(jiān)聽(tīng)與接收、Controller的激活、Controller的執(zhí)行以及View的呈現(xiàn)。這四個(gè)對(duì)象按照如右圖所示的順序相互協(xié)作完成對(duì)請(qǐng)求的處理。

如下所示的Listener、ControllerActivator、ControllerExecutor和ViewGenderer這四個(gè)類型的簡(jiǎn)單定義。我們沒(méi)有將它們定義成單純的抽象類或者接口,而是未被封閉可以被繼承的一般類型,定義其中的虛方法具有默認(rèn)的實(shí)現(xiàn)。只有這些默認(rèn)的實(shí)現(xiàn)方式無(wú)法滿足應(yīng)用程序具體需求的時(shí)候,我們才需要定義相應(yīng)的派生類。

 public class Listener
 {
 public virtual Request Listen(Uri address) ;
 }
 
 public class ControllerActivator
 {
 public virtual Controller ActivateController(Request request) ;
 }
 
 public class ControllerExecutor
 {
 public virtual View ExecuteController(Controller controller) ;
 }
 
 public class ViewRenderer
 {
 public virtual void RenderView(View view) ;
 }

在作為MVC引擎的MvcEngine類中,我們定義了四個(gè)工廠方法(GetListener、GetControllerActivator、GetControllerExecutor和GetViewRenderer)來(lái)提供上述這四種類型的對(duì)象。這四個(gè)工廠方法均為具有默認(rèn)實(shí)現(xiàn)的虛方法,它們默認(rèn)提供上述四種類型的對(duì)象。在用于啟動(dòng)引擎的Start方法中,我們利用這些工廠方法提供的對(duì)象來(lái)具體完成請(qǐng)求處理流程的各個(gè)核心環(huán)節(jié)。

 public class MvcEngine
 {
 public void Start(Uri address)
 {
  while (true)
  {
  Request request = this.GetListener().Listen(address);
  Task.Run(() =>
  {
   Controller controller = this.GetControllerActivator()
   .ActivateController(request);
   View view = this.GetControllerExecutor()
   .ExecuteController(controller);
   this.GetViewRenderer().RenderView(view);
  });
  }
 }
 
 protected virtual Listener GetListener()
 {
  return new Listener();
 }
 
 protected virtual ControllerActivator GetControllerActivator()
 {
  return new ControllerActivator();
 }
 
 protected virtual ControllerExecutor GetControllerExecutor()
 {
  return new ControllerExecutor();
 }
 
 protected virtual ViewRenderer GetViewRenderer()
 {
  return new ViewRenderer();
 }
 }

對(duì)于具體的應(yīng)用程序來(lái)說(shuō),如果需要對(duì)請(qǐng)求處理的某個(gè)環(huán)節(jié)進(jìn)行定制,它需要將定制的操作實(shí)現(xiàn)在對(duì)應(yīng)類型(Listener、ControllerActivator、ControllerExecutor和ViewGenderer)的派生類中。在MvcEngine的派生類中,我們需要重寫(xiě)對(duì)應(yīng)的工廠方法來(lái)提供被定制的對(duì)象。 比如上面提及的以單例模式提供目標(biāo)Controller對(duì)象的實(shí)現(xiàn)就定義在SingletonControllerActivator類中,我們?cè)谂缮贛vcEngine的FoobarMvcEngine類中重寫(xiě)了工廠方法GetControllerActivator使其返回一個(gè)SingletonControllerActivator對(duì)象。

 public class SingletonControllerActivator : ControllerActivator
 {
 public override Controller ActivateController(Request request)
 {
  <<省略實(shí)現(xiàn)>>
 }
 }
 
 public class FoobarMvcEngine : MvcEngine
 {
 protected override ControllerActivator GetControllerActivator()
 {
  return new SingletonControllerActivator();
 }
 }

上面我們采用工廠方法模式對(duì)MVC框架進(jìn)行了重新設(shè)計(jì),右圖清晰地展示了該框架以MvcEngine為核心的相關(guān)組件之間的相互關(guān)系,同時(shí)也體現(xiàn)了采用派生MvcEngine(FoobarMvcEngine)具體的應(yīng)用是如何通過(guò)重寫(xiě)工廠方法(GetControllerActivator)對(duì)框架實(shí)施定制的。

抽象工廠(Abstract Factory)

雖然工廠方法和抽象工廠均提供了一個(gè)“生產(chǎn)”對(duì)象實(shí)例的工廠,但是兩者在設(shè)計(jì)上卻有本質(zhì)的不同。工廠方法利用定義在某個(gè)類型的抽象方法或者虛方法實(shí)現(xiàn)了針對(duì)單一對(duì)象提供方式的抽象,而抽象工廠在利用一個(gè)獨(dú)立的接口或者類來(lái)實(shí)現(xiàn)對(duì)一組相關(guān)對(duì)象提供的抽象。

具體來(lái)說(shuō),我們需要定義一個(gè)獨(dú)立的工廠接口或者抽象工廠類,并在其中定義多個(gè)的工廠方法來(lái)提供“同一系列”的多個(gè)相關(guān)對(duì)象。如果希望抽象工廠具有一組默認(rèn)的“產(chǎn)出”,我們也可以將一個(gè)未被封閉的具體類作為抽象工廠,以虛方法形式定義的工廠方法將默認(rèn)的對(duì)象作為返回值。我們根據(jù)實(shí)際的需要通過(guò)實(shí)現(xiàn)工廠接口或者繼承抽象工廠類(不一定是抽象類)定義具體工廠類來(lái)提供一組定制的系列對(duì)象。

現(xiàn)在我們采用抽象工廠模式來(lái)改造我們的MVC框架。如下面的代碼片段所示,我們定義了一個(gè)實(shí)例類EngineFactory作為創(chuàng)建MvcEngine所需四種對(duì)象(Listener、ControllerActivator、ControllerExecutor和ViewGenderer)的抽象工廠,定義其中的四個(gè)工廠方法的返回值體現(xiàn)了工廠默認(rèn)的產(chǎn)出。我們?cè)趧?chuàng)建MvcEngine對(duì)象可以提供一個(gè)具體的EngineFactory對(duì)象(如果沒(méi)有顯式指定,MvcEngine默認(rèn)使用的是一個(gè)自動(dòng)創(chuàng)建的EngineFactory對(duì)象)。在用于啟動(dòng)引擎的Start方法中,MvcEngine利用EngineFactory來(lái)獲取相應(yīng)的對(duì)象協(xié)作完整對(duì)請(qǐng)求的處理流程。 對(duì)于我們采用抽象工廠改造后的MVC框架,以MvcEngine為核心的相關(guān)組件之間的關(guān)系體現(xiàn)在如左圖所示的UML中。

 public class EngineFactory
 {
 public virtual Listener GetListener()
 {
  return new Listener();
 }
 
 public virtual ControllerActivator GetControllerActivator()
 {
  return new ControllerActivator();
 }
 
 public virtual ControllerExecutor GetControllerExecutor()
 {
  return new ControllerExecutor();
 }
 
 public virtual ViewRenderer GetViewRenderer()
 {
  return new ViewRenderer();
 }
 }
 
 public class MvcEngine
 {
 public EngineFactory Factory { get; private set; }
 
 public MvcEngine(EngineFactory factory = null)
 {
  this.Factory = factory ?? new EngineFactory();
 }
 
 public void Start(Uri address)
 {
  while (true)
  {
  Request request = this.Factory.GetListener().Listen(address);
  Task.Run(() =>
  {
   Controller controller = this.Factory.GetControllerActivator()
   .ActivateController(request);
   View view = this.Factory.GetControllerExecutor()
   .ExecuteController(controller);
   this.Factory.GetViewRenderer().RenderView(view);
  });
  }
 }
 } 

如果具體的應(yīng)用程序需要采用上面定義的SingletonControllerActivator以單例的模式來(lái)激活目標(biāo)Controller,我們可以按照如下的方式定義一個(gè)具體的工廠類FoobarEngineFactory。最終的應(yīng)用程序?qū)⑦@么一個(gè)FoobarEngineFactory對(duì)象作為MvcEngine的EngineFactory。

 public class FoobarEngineFactory : EngineFactory
 {
 public override ControllerActivator GetControllerActivator()
 {
  return new SingletonControllerActivator();
 }
 }
 
 public class App
 {
 static void Main(string[] args)
 {
  Uri  address = new Uri("http://localhost/mvcapp");
  MvcEngine engine = new MvcEngine(new FoobarEngineFactory());
  Engine.Start(address);
 }
 }

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • asp.net 簡(jiǎn)便無(wú)刷新文件上傳系統(tǒng)

    asp.net 簡(jiǎn)便無(wú)刷新文件上傳系統(tǒng)

    之前寫(xiě)過(guò)一個(gè)仿163網(wǎng)盤無(wú)刷新多文件上傳系統(tǒng),已經(jīng)對(duì)無(wú)刷新上傳文件的原理做了詳細(xì)的分析而這次的系統(tǒng)主要是針對(duì)單個(gè)file控件的,便攜版,使用更簡(jiǎn)單,還有更深入的分析
    2012-05-05
  • .NET邏輯分層架構(gòu)總結(jié)

    .NET邏輯分層架構(gòu)總結(jié)

    本人將從另一個(gè)角度來(lái)解析.NET分層架構(gòu)的真正奧秘。分層,一些技術(shù)功底比較薄弱的程序員聽(tīng)到分層就會(huì)聯(lián)想到三層架構(gòu)(BLL,DAL之類的),其實(shí)不是,分層是一個(gè)很大的技術(shù)框架思想,三層架構(gòu)只不過(guò)是對(duì)普通的信息系統(tǒng)來(lái)說(shuō),將信息的流轉(zhuǎn)通過(guò)三層來(lái)分解,
    2015-06-06
  • asp.net Web Service 接口大量數(shù)據(jù)傳輸解決方案

    asp.net Web Service 接口大量數(shù)據(jù)傳輸解決方案

    就管他叫“使用多線程分段獲取大量數(shù)據(jù)方法”吧。假定我們的需求是,通過(guò)Web Service獲取10W條訂單,我的解決方案是 分成10個(gè)線程每個(gè)線程傳輸1W條訂單分段獲取
    2010-04-04
  • Asp.net利用JQuery AJAX實(shí)現(xiàn)無(wú)刷新評(píng)論思路與代碼

    Asp.net利用JQuery AJAX實(shí)現(xiàn)無(wú)刷新評(píng)論思路與代碼

    Asp.net利用JQuery AJAX實(shí)現(xiàn)無(wú)刷新評(píng)論,此功能是每一個(gè)從事asp.net開(kāi)發(fā)者的朋友都希望實(shí)現(xiàn)的,本文利用閑暇時(shí)間整理了一些,有需要的朋友可以參考下
    2012-12-12
  • Asp.net 頁(yè)面調(diào)用javascript變量的值

    Asp.net 頁(yè)面調(diào)用javascript變量的值

    開(kāi)發(fā)過(guò)程中碰到了這種情況,我想將javascript中定義的變量賦值給頁(yè)面中的TextBox控件.
    2009-12-12
  • 輕量級(jí)ORM框架Dapper應(yīng)用之實(shí)現(xiàn)DTO

    輕量級(jí)ORM框架Dapper應(yīng)用之實(shí)現(xiàn)DTO

    本文詳細(xì)講解了使用Dapper實(shí)現(xiàn)DTO的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • 批量賬號(hào)的login測(cè)試功能實(shí)現(xiàn)

    批量賬號(hào)的login測(cè)試功能實(shí)現(xiàn)

    用WaitiN寫(xiě)了個(gè)簡(jiǎn)單的login自動(dòng)化測(cè)試,能夠使用少量的代碼實(shí)現(xiàn)批量賬號(hào)的login測(cè)試,需要的朋友可以參考下
    2012-11-11
  • 在ASP.NET中下載文件的實(shí)現(xiàn)代碼

    在ASP.NET中下載文件的實(shí)現(xiàn)代碼

    通過(guò)ASP.NET來(lái)下載文件,這個(gè)問(wèn)題可大可小,我們先從小的開(kāi)始。當(dāng)我們要讓用戶下載一個(gè)文件
    2012-02-02
  • ASP.NET中的DataGridView綁定數(shù)據(jù)和選中行刪除功能具體實(shí)例

    ASP.NET中的DataGridView綁定數(shù)據(jù)和選中行刪除功能具體實(shí)例

    廢話就不多說(shuō)了,都說(shuō).NET是托控件的,我就托給你們看,這個(gè)博文主要講 DataGridView 的數(shù)據(jù)綁定,和選中行刪除功能
    2013-12-12
  • .NET Core 2.1中HttpClientFactory的最佳實(shí)踐記錄

    .NET Core 2.1中HttpClientFactory的最佳實(shí)踐記錄

    這篇文章主要給大家介紹了關(guān)于.NET Core 2.1中HttpClientFactory的最佳實(shí)踐記錄,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用.net core2.1具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧
    2018-08-08

最新評(píng)論