控制反轉(Ioc)和依賴註入(DI)

来源:http://www.cnblogs.com/Dlonghow/archive/2016/04/21/5415421.html
-Advertisement-
Play Games

控制反轉IOC, 全稱 “Inversion of Control”。依賴註入DI, 全稱 “Dependency Injection”。 面向的問題:軟體開發中,為了降低模塊間、類間的耦合度,提倡基於介面的開發,那麼在實現中必須面臨最終是有“誰”提供實體類的問題。(將各層的對象以松耦合的方式組織起 ...


控制反轉IOC, 全稱 “Inversion of Control”。依賴註入DI, 全稱 “Dependency Injection”。

面向的問題:軟體開發中,為了降低模塊間、類間的耦合度,提倡基於介面的開發,那麼在實現中必須面臨最終是有“誰”提供實體類的問題。(將各層的對象以松耦合的方式組織起來,各層對象的調用面向介面。)

當一個類的實例需要另一個類的實例協助時,在傳統的程式設計過程中,通常有調用者來創建被調用者的實例。

然後,採用依賴註入原則,創建被調用者的實例的工作不再由調用者完成,而是由IOC容器來完成,這就是“控制反轉”的意思,然後,將其註入調用者,因此也稱為 “依賴註入”。

Martin Fowler,在其著名的文章《Inversion of Control Containers and the Dependency Injection pattern》中將具體依賴註入劃分為三種形式,即構造器註入、屬性(設置)註入和介面註入。

習慣將其劃分為一種(類型)匹配和三種註入:

  • 類型匹配(Type Matching):雖然我們通過介面(或者抽象類)來進行服務調用,但是服務本身還是實現在某個具體的服務類型中,這就需要某個類型註冊機制來解決服務介面和服務類型之間的匹配關係;
  • 構造器註入(Constructor Injection):IoC容器會智能地選擇選擇和調用適合的構造函數以創建依賴的對象。如果被選擇的構造函數具有相應的參數,IoC容器在調用構造函數之前解析註冊的依賴關係並自行獲得相應參數對象;
  • 屬性註入(Property Injection):如果需要使用到被依賴對象的某個屬性,在被依賴對象被創建之後,IoC容器會自動初始化該屬性;
  • 方法註入(Method Injection):如果被依賴對象需要調用某個方法進行相應的初始化,在該對象創建之後,IoC容器會自動調用該方法

創建一個控制台程式,定義如下幾個介面(IA、IB、IC和ID)和它們的實現類(A、B、C、D)。在類型A中定義了三個屬性B、C和D,其參數類型分別為IB、IC和ID。

其中,

屬性B作為構函數的參數,認為它會以構造器註入的方式被初始化 (??);

屬性C應用了DependencyAttribute特性,意味著這是一個需要以屬性註入方式被初始化的依賴屬性;

屬性D則通過方法Initialize初始化,該方法上應用了特性InjectionMethodAttribute, 意味著這是一個方法註入,在A對象被Ioc容器創建的時候,D會被自動調用。

 

Microsoft有一個輕量級的IoC框架Unity, 支持構造器註入,屬性註入,方法註入。對於C#語言,由於語法元素上本身較其他語言豐富許多,如何實施註入還有些技巧和特色之處。

下麵介紹如下:

測試類:

namespace UnityDemo
{
    public interface IA { }
    public interface IB { }
    public interface IC { }
    public interface ID { }

    public class A : IA
    {
        public IB B { get; set; }

        [Dependency]
        public IC C { get; set; }
        public ID D { get; set; }

        public A(IB b)
        {
            this.B = b;
        }

        [InjectionMethod]
        public void Initialize(ID d)
        {
            this.D = d;
        }
    }

    public class B : IB { }
    public class C : IC { }
    public class D : ID { }
}

配置註冊:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
    </configSections>
    <unity>
        <containers>
            <container name="defaultContainer">
                <register type="UnityDemo.IA, UnityDemo" mapTo="UnityDemo.A, UnityDemo"/>
                <register type="UnityDemo.IB, UnityDemo" mapTo="UnityDemo.B, UnityDemo"/>
                <register type="UnityDemo.IC, UnityDemo" mapTo="UnityDemo.C, UnityDemo"/>
                <register type="UnityDemo.ID, UnityDemo" mapTo="UnityDemo.D, UnityDemo"/>
            </container>
        </containers>
    </unity>

    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
</configuration>

Main方法中,創建一個Ioc容器的UnityContainer對象,並載入配置信息對其初始化,然後調用它的泛型的Resolve方法創建一個實現了泛型介面IA的對象。

最後將返回對象轉換成類型A, 並逐一檢驗B,C和D屬性是否為空,即初始化情況。

namespace UnityDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var container = new UnityContainer();
            var configuration = ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection;
            configuration.Configure(container, "defaultContainer");

            A a = container.Resolve<IA>() as A;
            if (null != a)
            {
                Console.WriteLine("a.B==null? {0}", a.B == null ? "Yes" : "No");
                Console.WriteLine("a.C==null? {0}", a.C == null ? "Yes" : "No");
                Console.WriteLine("a.D==null? {0}", a.D == null ? "Yes" : "No");
            }

        }
    }
}

 

執行結果:

 

分別體現了介面註入、構造器註入(屬性B)、屬性註入(屬性C)和方法註入(屬性D)。

 

JACK D. @ NJ USA

 


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

-Advertisement-
Play Games
更多相關文章
  • 今天學到了很有意思的三個命令:怎麼有意思 快看下圖啦! 這是Ubuntu系統下的三個命令,跟echo本質一樣,但是輸出的字元是圖形的 ,很可愛! 以下是安裝命令: sudo apt-get update;sudo apt-get install sysvbanner sudo apt-get upd ...
  • 磁碟分析 本機的系統盤是C盤,操作系統是Windows 7 專業版,通過磁碟屬性可以看到C盤的已用空間是69.4G。 而我們運行自己編寫的腳本(腳本程式參考附錄,統計原理:計算目錄下各個文件的大小,然後相加,即為該目錄的大小;再將各個目錄占用空間相加,即為總的占用空間),可以發現,占用空間為59G。 ...
  • 由於需要安裝hadoop集群,有10台機器需要安裝,一開始打算用SCP複製,後來覺得不可接受(實際現場可能數倍的機器集群,就是10台也不想乾)。後來在網上找了,發現了clustershell和pssh這兩個工具。這兩個工具隨便用其中一個就可以了。 環境說明:centos6.5機器10台 需求:確定一... ...
  • 我第一次接觸“線程”的概念時,覺得它深奧難懂,看了好多本書,花了很長時間才領悟到它的真諦。現在我就以一個初學者的心態,把我所理解的“多線程”描述給大家。這一次是系列文章,比較完整的展示與線程相關的基本概念。希望對初學者有所幫助。 如果你是高手,請你別繼續看,會浪費你寶貴的時間。 一、基本概念 什麼是 ...
  • 我們在做開發的時候,很多時候需要和Json數據格式打交道,如Web開發裡面,很多時候,數據通過Json進行傳遞到頁面上,然後在進行處理的。而使用Json的時候,我們很多時候會涉及到幾個序列化對象的使用:DataContractJsonSerializer,JavaScriptSerializer 和 ...
  • 概述 BPEL:全稱為Business Process Execution Language,即業務流程執行語言,是一種使用XML編寫的編程語言。用於自動化業務流程,也曾經被稱作WSBPEL和 BPEL4WS。廣泛使用於Web服務相關的項目開發中,優點為具有可移植性和有效保護了投資。 BPEL是一門 ...
  • c# 操作 xml 在System.XMl 有以個類可以操作xml (網上對這些類的記錄真得很少啊 可能因為類比較多吧 msdn的介紹) 創建一個新的xml XmlDocument xmldoc = new XmlDocument(); //在XML的文檔的最頭部加入XML的聲明段落 XmlNode ...
  • 分類:Unity、C#、VS2015 創建日期:2016-04-21 一、簡介 Unity提供了—個非常易用和強大的用於處理輸入信息的類:Input,利用該類可以處理滑鼠、鍵盤、搖桿/方向盤/手柄等游戲外設,也可以處理iOS/Androd等移動設備的觸摸輸入信息。 程式員通過編寫腳本接收輸入信息,完... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...