程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Unity Application Block 1.0系列(2):構造子注入(Constructor Injection)

Unity Application Block 1.0系列(2):構造子注入(Constructor Injection)

編輯:關於.NET

什麼情況下使用Constructor Injection

當實例化父對象時也能自動實例化所依賴的對象

通過簡單的方式使得很容易做到在代碼中查看每個類所依賴的項

父對象的構造器不需要很多相互間有關聯關系的構造器

父對象的構造器不需要很多參數

通過不使用屬性和方法暴露給調用程序,達到封裝字段值以不能被看到的目的

通過修改依賴對象的代碼來控制哪些對象可以被注入,而不用改動父對象或應用程序

准備工作

public class Song
{
  public string Singer
  {
    get
    {
      return "Westlife";
    }
  }

  public string Name
  {
    get
    {
      return "My Love";
    }
  }
}

public class Owner
{
  public string Name
  {
    get
    {
      return "Inrie";
    }
  }

  public int Age
  {
    get
    {
      return 24;
    }
  }
}

public interface IPlayer
{
  void Play();
}

開始

根據類構造器的個數分成下面兩種情況:

1.單個構造器

2.多個構造器

1.單個構造器:

Unity對於單個構造器的情況,將做自動的依賴注入。

看個例子:

public class Mp3Player : IPlayer
{
  public Song mSong;

  public Mp3Player(Song song,Owner owner)
  {
    this.mSong = song;
  }

  public void Play()
  {
    Console.WriteLine(string.Format("Now Playing [{0}] Singing by ({1})", this.mSong.Name, this.mSong.Singer));
  }
}

可以通過下面的方式來獲取Mp3Player對象實例。

IUnityContainer container = new UnityContainer();
container.RegisterType<IPlayer, Mp3Player>();

IPlayer player = container.Resolve<IPlayer>();
player.Play();

輸出為:

上例中Mp3Player類中只有一個構造器,該構造器依賴於兩個類:Song和Owner類。Unity容器在執行Resolve方法時會自動裝配所依賴類的實例,注入到構造器中。

當類中只有一個構造器時,Unity容器在裝配時自動以此構造器為默認構造器。

2.多個構造器:

Unity對於多個構造器的情況,需要配合[InjectionConstructor]特性來實現依賴注入。

有以下幾個原則:

A.有加上[InjectionConstructor]標簽的構造器為依賴注入的構造器

public class Mp3Player : IPlayer
{
  public Song mSong;

  [InjectionConstructor]
  public Mp3Player(Owner owner)
  {

  }

  public Mp3Player(Song song,Owner owner)
  {
    this.mSong = song;
  }

  public void Play()
  {
    Console.WriteLine(string.Format("Now Playing [{0}] Singing by ({1})", this.mSong.Name, this.mSong.Singer));
  }
}

該例中為 Mp3Player(Owner owner) 構造器貼上[InjectionConstructor]標簽,所以該構造器將作為依賴注入的構造器。

B.如果沒有任何構造器有貼上[InjectionConstructor],則使用參數最多的構造器作為依賴注入的構造器

public class Mp3Player : IPlayer
{
  public Song mSong;

  public Mp3Player(Owner owner)
  {

  }

  public Mp3Player(Song song,Owner owner)
  {
    this.mSong = song;
  }

  public void Play()
  {
    Console.WriteLine(string.Format("Now Playing [{0}] Singing by ({1})", this.mSong.Name, this.mSong.Singer));
  }
}

該例中由於有多個構造器,同時也沒有為任何一個構造器貼上[InjectionConstructor]標簽,則使用參數最多的構造器,即Mp3Player(Song song,Owner owner)構造器作為依賴注入的構造器。

這裡有一點需要注意:如果有多個構造器都是屬於"參數最多"的構造器,則會出現錯誤。

注入到存在的對象實例

用Resolve方法來獲取已存在的對象實例時不會做 Constructor Injection,因為該對象的創建沒受到 Unity 容器的任何影響。甚至用BuildUp方法也不行。作為取代的方法,可以采用 Property Injection。

關於BuildUp方法可參考:

Unity Application Block 1.0系列(5): 使用BuildUp讓對象實例也支持依賴注入

關於Property Injection可參考:

Unity Application Block 1.0系列(3): 屬性/設值方法注入(Property/Setter Injection)

結束語

在Unity幫助文檔裡有專門提到:“如果你不確信要使用哪種注入方式,建議還是使用Constructor Injection。它更符合幾乎所有的一般需求。”

另外使用Constructor Injection還需要特別注意不要有循環引用,否則可能會導致應用程序出錯,至於循環引用的具體說明會有專門一篇文章介紹。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved