Ioc 器管理的應用程式設計,前奏:容器屬於哪裡?

来源:https://www.cnblogs.com/gdsblog/archive/2018/03/31/8681526.html
-Advertisement-
Play Games

我將討論一些我認為應該應用於“容器管理”應用程式設計的原則。 模式1:服務字典 字典或關聯數組是我們在軟體工程中學到的第一個構造。 很容易看到使用依賴註入組成對象的字典和IoC容器之間的類比: 未使用容器 使用容器 這兩看起來不同的是: 一些花哨的新術語'Register'和'Resolve'被使用 ...


我將討論一些我認為應該應用於“容器管理”應用程式設計的原則。

模式1:服務字典

字典或關聯數組是我們在軟體工程中學到的第一個構造。 很容易看到使用依賴註入組成對象的字典和IoC容器之間的類比:

未使用容器

使用容器

這兩看起來不同的是:

一些花哨的新術語'Register'和'Resolve'被使用,而不是索引器訪問

記錄器是通過反射創建的,在相互依賴的情況下保存一些打字和配置代碼

如果你進入一個已經建立了依賴註入容器的項目,並且必須弄清楚如何編寫你需要與系統的其他部分進行交互的代碼。

模型2:抽象 new()運算符

經常稱贊依賴註入容器是為了消除實現類型依賴。回到我們的例子,我們已經提出了一個獨立於提供它的實現類型的ILogger請求(在這種情況下為ConsoleLogger)。

ASP.NET MVC等Web框架使用我們的依賴註入容器以類似的方式創建Controller實例。

將容器想象為一個抽象的new()運算符會更有意義?

將上面代碼重構成下麵代碼

下麵代碼

在這裡,我們的容器使用不僅抽象出了我們的MailTransport的具體類型,還負責配置其主機屬性。 (配置必須是我們的abstract new()運算符的一個特性,因為實例上的配置參數取決於它的具體類型而不是它提供的服務。)

設計成果:the Global Container

遵循這些思想模式之一鼓勵您將容器視為您從中檢索的東西。即使是“容器”這個名字也會推動我們朝這個方向發展。

從這個角度來看,應用程式架構設計任務中沒有太多的挑戰!

我們將在一個類上創建一個靜態屬性Container,例如Global,並使用Global.Container.Resolve <MyService>()從它獲取實例。

 

這段代碼應該熟悉另一個名稱的模式:靜態服務定位器(the static Service Locator)。

the Global Container 作為服務定位器的問題

這種模式可以被正確地稱為反模式有充分的理由:


脆弱性。容器就像一桶全局變數。強制組件公開聲明依賴關係所實現的所有健壯性都會丟失。意外的依賴關係可能出現在應用程式的看似無關的部分之間,使維護變得複雜。


降低組合性。當註入依賴關係時,可以將容器配置為向不同的消費者提供不同的實現。組合獨立構建的組件時,這通常是必需的。當從全局容器檢索依賴項時,容器不知道請求者的身份,並且每次都被迫返回相同的實現。


有限的重用。全局容器所在的位置可能會限制依賴於它的組件的可重用性。將組件遷移到WPF應用程式將需要更改代碼,如果它們依賴於附加到HttpApplication類的全局容器。


實施問題。在全球基於容器的解決方案中,併發性,重入性,迴圈引用檢測和組件生命周期管理更加困難/混亂。


恢復控制:一般來說,這些問題的產生是因為直接調用全球容器是恢復控制。在容器管理的應用程式中,容器負責將正確的實例放到正確的位置以完成工作。調用一個全球容器以一種不易管理的方式來承擔一部分責任。

有時候,由於許多當代框架中的設計決策,the Global Container是必要的,但為了推進軟體工程的發展,我們需要超越這一點。

箱子里的思考

上面列出的心理模型應該已經敲響了一些警鐘:

該容器是一個服務字典? 不掛斷! 如果我兩次要求同樣的服務,為什麼我有時會得到不同的實例?

好問題。 配置一個依賴註入容器很容易,每次解析時都會返回一個新的ConsoleLogger實例。 不是很像字典,是嗎?

所以容器真的是一個抽象的new()操作符? 等待! 如果我有時得到相同的共用實例,我何時可以Dispose()它?

這兩種模式甚至不相容。 有時候容器提供了新的實例,但有時從調用中返回的是一個單例,或者是一個將在某種上下文中共用的實例,比如當前事務。

所以事情現在令人困惑。

修訂後的思想模型:一個互相關聯的對象系統

問題來了:看看Autofac主頁上的例子。 它顯示了Autofac中如何使用Register()和Resolve()。 這是依賴註入的一個相當常見的例子。 註意缺少了什麼?

此示例中最重要的類不是ContainerBuilder或Container。 從應用程式架構的角度來看,我們需要看到Straight6TwinTurbo和Car類!

解析操作只是找到一個獨立系統的入口點的一種方法。

整個應用程式駐留在容器中。 除了無論什麼入場點滾球,都沒有“外線”。 從這個角度理解IoC並不是圍繞像Register()和Resolve()這樣的外部API。

 

使用這個模型,容器能夠在合適的時間將組件實例放在正確的位置,應用程式設計重新關註組件本身的實現。

設計結果:註入上下文

在實施我們改進的IControllerProvider時,這個世界的新視角給我們帶來了挑戰。 該服務需要返回(可能)新的,參數化的Controller類型實例。

通常在當今應用中實現的解決方案是允許容器為控制器提供商提供上下文:

 

我們在這裡假設ControllerProvider本身在容器中托管。 IContext是Autofac自動提供給需要它的任何組件的介面。 您可以在任何其他流行的IoC容器中創建和使用等效界面(以下鏈接了一個MEF示例)。

IContext以可控方式嚮應用程式提供容器的實例解析功能。 實現IContext的對象提供了容器的服務,但可能不是容器本身。

由於此模式為容器或應用程式開發人員提供了定製或代理髮送給任何特定組件的IContext實現的機會,因此與全局容器關聯的大多數問題都會得到緩解。

容器管理的應用程式設計

如果你覺得這篇文章及其解釋有些不完整,那你是對的。 正如這篇文章的標題所表明的那樣,它是關於該主題的一系列介紹。 我沒有全部的答案,我甚至沒有全部的問題.。

【本文為本人翻譯,原文查看


近期在搞區塊鏈方面的技術,同時本公眾號也會分享關於.net core的技術文章,歡迎大家關註!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 概述 New UWP Community Toolkit V2.2.0 的版本發佈日誌中提到了 Carousel 的調整,本篇我們結合代碼詳細講解 Carousel 的實現。 Carousel 是一種傳送帶形態的控制項,在圖片展示類的應用中有非常多的應用,它擁有很好的流暢度,可以做很多的自定義,並集成 ...
  • 本文告訴大家一個簡單的方法從 BBcode 轉為 Markdown ...
  • 本文告訴大家一個特殊的做法,可以修改一個字元串常量 <! more 我們來寫一個簡單的程式,把一個常量字元串輸出 其中的 Foo 是其他的函數,大家可以猜到輸出是 lindexi ,但是,實際上把Foo調用函數添加之後,輸出是 Lindexi 被大寫了。那麼這時 Foo 做了什麼? Foo 做的就是 ...
  • 如果需要做一個類的重寫,需要重新寫這個類的所有屬性和函數,本文提供一個簡單的方法讓大家快速重寫一個類的所有屬性和函數 ...
  • 本文依舊是一篇譯文,寫於作者在開發.net core 半年後的進階學習時刻! 這篇文章很長,一口氣看完得花二十分鐘,大家要做好心理準備! 摘要:Java社群近來掀起了一陣輕量級容器的熱潮,這些容器能夠幫助開發者將來自不同項目的組件組裝成為一個內聚的應用程式。在它們的背後有著同一個模式,這個模式決定了 ...
  • 1.const是不變常量,在編譯的時候就需要有確定的值,只能用於數值和字元串,或者引用類型只能為null.(這裡為什麼要把字元串單獨拿出來?是因為字元串string是引用類型,但是使用的時候卻感覺是值類型,它是一種特殊的引用類型,後面會詳細說),struct也不能用const標記。const可以修飾 ...
  • 概述 前面 New UWP Community Toolkit 文章中,我們對 2.2.0 版本的重要更新做了簡單回顧,其中簡單介紹了 Staggered panel,本篇我們結合代碼詳細講解 Staggered panel 的實現。 Staggered panel 是一種交錯排列的面板控制項,允許面 ...
  • 上周需要做一個圖片上傳並且將上傳的圖片線上可以裁剪展示,覺得這個功能很有用,但是找參考資料的時候卻並不是很多,因此來將我用到的總結總結,也讓有需要的博友們直接借鑒。 首先環境介紹: 1、asp.net mvc網站,用到的前端插件是JCrop和Bootstrap-fileinput,在後端用框架自帶的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...