1. 程式人生 > 程式設計 >詳解C# 依賴注入

詳解C# 依賴注入

前言

  好久沒有寫微博了,因為前段時間由於家庭原因決定從工作了3年多的北京轉移到上海去。依賴注入在學習net core的時候也有寫過類似的東西,只是實踐的較少,結果來到上海新公司系統框架涉及到了這塊知識點,所以在瞭解完自己的專案之後決定做一些相關的總結。接下來就讓我們先來了解hewi依賴注入。

什麼是依賴注入

  依賴注入,全稱是“依賴注入到容器”, 容器(IOC容器)是一個設計模式,它也是個物件,你把某個類(不管有多少依賴關係)放入這個容器中,可以“解析”出這個類的例項。所以依賴注入就是把有依賴關係的類放入容器(IOC容器)中,然後解析出這個類的例項。劃重點:依賴注入是為了實現控制反轉的一種設計模式。【現在知道gof之外還有其他的設計模式了吧。】

為什麼要用依賴注入

  我們程式設計希望高內聚低耦合,所以解耦是很多理論的出發點,依賴注入控制反轉也是為了解耦。那麼冒昧問一下啊低耦合是什麼?我的理解就是:我們在程式設計過程中,我們不需要知道元件與類庫的內容只需知道他們提供的介面,呼叫介面就能實現功能,我們就說這種情況是低耦合。

  在沒有接觸到依賴注入的時候,解耦的思路其實也就是gof設計模式和設計原則。我以前分享的很多文章牽涉到的封裝類庫都是基於面向介面的方式。舉個例子:

public interface IOrder
{
//Product 產品物件
decimal ValueProducts(params Product[] products);
}

public class Order : IOrder
{
public decimal ValueProducts(params Product[] products)
{
return products.Sum(p => p.Price*p.Number);
}
}

以上是在做商城經常寫的一個基類。比如我們以前商城中購物車下單就算其總價的方法呼叫的時候。

public class ShoppingCart
    {
      //計算購物車內商品總價錢
      public decimal CalculateStockValue()
      {
        Product[] products = {
       new Product {Name = "龍牙2016新款",Number=2,ModelNo = 121,ColorID=65,SizeID=78,Price = 289.40},new Product {Name = "龍牙2017新款",Price =3800},};
        IOrder order = new Order();
        //計算商品總價錢 
        decimal totalValue = order.ValueProducts(products);
        return totalValue;
      }
    }

以上是我常用的方式來處理自己的業務需求的。這種面向介面的方式,如果我們要計算金額的方式改變了,比如我們尺寸32的金額打7折,那麼只需增加金額的類。改變介面例項化即可。程式碼就不敲了應該都懂吧(低耦合)。那麼我們可以看出ShoppingCart是依賴於介面與實現的對不對,那麼現在我們考慮一個問題,購物車雖然呼叫介面例項化,但是它也是要依賴於order的,那麼減少它的依賴性有沒有辦法——就是把他們完全分開。那麼這種問題的解決就用到了依賴注入了。劃重點:依賴注入就是減少對介面例項化物件的依賴。那麼怎麼來實現依賴注入呢?

構造注入的實現

通過類的建構函式

第一次看net core別人也是講的這種方式,下面看一下程式碼。設定一個服務類介面型別的資料成員,並以建構函式為注入點,這個建構函式接受一個具體的服務類例項為引數,並將它賦給服務類介面型別的資料成員。

public class ShoppingCart
    {
      IOrder order;
      //建構函式,引數為實現了IOrder 介面的類的例項
      public ShoppingCart(IOrder _order)
      {
        order = _order;
      }
      //計算購物車內商品總價錢
      public decimal CalculateStockValue()
      {
        Product[] products = {
          new Product {Name = "龍牙2016新款",Price =3800}}; //計算商品總價錢
        decimal totalValue = order.ValueProducts(products);
        return totalValue;
      }

以上程式碼最秒的地方就是ShoppingCart與介面IOrder的實現order完全沒有關係,不需要了解他是怎麼實現的。這就是依賴注入。這種叫做構造注入。

在我們討論下一種注入的方式的時候,有個問題其實還沒有解決。“依賴是如何產生的?”把依賴當作建構函式引數來寫,儘管使用這可以手動提供這種依賴,但是當整個系統都依賴注入,那就意味著任何一個元件我們都需要知如道滿足每一部分的需求(服務定位器),是不是很頭大?那麼這時我們就要要引入一個概念的“容器”-----依賴注入容器。

protected override void RegisterBuilder(ContainerBuilderWrapper builder)
    {
      base.RegisterBuilder(builder);      //注入倉儲
      builder.RegisterType<Order>().As<IOrder>();
    }

以上為mvc容器的一種實現。AS 後邊是服務類繼承的介面,其實我對它的理解就是:如果有人請求這種型別。我們就給他這個型別的物件。

屬性注入

其實依賴注入spring相關的資料應該有很多,所以很多知識點也是通過java那的理論借鑑過來的。屬性注入我確實看的net的書瞭解的。

如果需要使用到被依賴物件的某個屬性,在被依賴物件被建立之後,IoC容器會自動初始化該屬性

首先還是定一個介面

public interface Iorder
    {
      {
      //Product 產品物件
      decimal ValueProducts(params Product[] products);
      }
    }

屬性注入如下:

public class ShoppingCart
    {
      private iordre _order;
      public iordre Order
      {
        get { return _order; }
        set { _order = value; }
      }
      public decimal ValueProducts(params Product[] products)
      {
        return Order.ValueProducts(products);
      }
    }

Setter注入

設定一個服務類介面型別的資料成員,並設定一個Set方法作為注入點,這個Set方法接受一個具體的服務類例項為引數,並將它賦給服務類介面型別的資料成員。其實這種是注入方式較為靈活使用者也較多。

//服務介面
    internal interface IServiceClass
    {
      String ServiceInfo();
    }

    //服務方法
    internal class ServiceClassA : IServiceClass
    {
      public String ServiceInfo()
      {
        return "我是ServceClassA";
      }
    }
    //服務方法
    internal class ServiceClassB : IServiceClass
    {
      public String ServiceInfo()
      {
        return "我是ServceClassB";
      }
    }
    //客戶類實現set
    internal class ClientClass
    {
      private IServiceClass _serviceImpl;

      public void Set_ServiceImpl(IServiceClass serviceImpl)
      {
        this._serviceImpl = serviceImpl;
      }

      public void ShowInfo()
      {
        Console.WriteLine(_serviceImpl.ServiceInfo());
      }
    }

    //呼叫
    class Program
    {
      static void Main(string[] args)
      {
        IServiceClass serviceA = new ServiceClassA();
        IServiceClass serviceB = new ServiceClassB();
        ClientClass client = new ClientClass();

        client.Set_ServiceImpl(serviceA);
        client.ShowInfo();
        client.Set_ServiceImpl(serviceB);
        client.ShowInfo();
      }
    }

結束語

其實依賴注入可聊的有很多,net core的出現依賴注入是必不可少的一個知識點。後面可聊的比如依賴注入與反射,依賴注入與多型,依賴注入的框架。。。。。。。

好久不寫部落格,準備的也不夠充分。有興趣的小夥伴就去網上找去吧。

.net書的話:

《asp net mvc5 高階程式設計》《Dependency Injection in .NET 》(沒有中文)

java相關的書應該會多一些。有興趣的就一起學習一下吧。

以上就是詳解C# 依賴注入的詳細內容,更多關於c# 依賴注入的資料請關注我們其它相關文章!