什麼情況下使用Method Call Injection
當執行個體化父物件時也能自動執行個體化所依賴的對象
通過簡單的方式使得很容易做到在代碼中查看每個類所依賴的項
父物件有很多相互之間有關聯關係的構造器,導致在調試和維護時很不方便
父物件包含有很多參數構造器,特別是參數類型相似的只能通過參數的位置來辨別的
隱藏依賴的對象,不作為屬性暴露出去
通過修改依賴對象的代碼來控制哪些對象可以被注入,而不用改動父物件或應用程式
準備工作
public interface IPlayer
{
void Play();
}
public class Mp3Player : IPlayer
{
public Song mSong;
[InjectionMethod]
public void Init(Song song)
{
this.mSong = song;
}
public void Play()
{
Console.WriteLine(string.Format("{0}: Now Playing [{1}] Singing by ({2})", this.Name, this.mSong.Name, this.mSong.Singer));
}
public string Name
{
get
{
return "Mp3 Player";
}
}
}
開始
Constructor Injection在容器建立對象執行個體時就會觸發執行,而Method Call Injection在具體調用對象執行個體的方法時候才觸發。
通過為類的方法貼上[InjectionMethod]標籤,使得Unity容器在擷取類對象執行個體時,自動執行個體化該方法所依賴的對象,注入到該方法中。
看一個例子:
Mp3Player類中為Init(Song song)方法貼上了[InjectionMethod]標籤:
[InjectionMethod]
public void Init(Song song)
{
this.mSong = song;
}
可以通過下面的方式來擷取Mp3Player對象執行個體:
IUnityContainer container = new UnityContainer();
container.RegisterType<IPlayer, Mp3Player>();
IPlayer player = container.Resolve<IPlayer>();
player.Play();
輸出:
這裡通過為Mp3Player類的Init方法貼上[InjectionMethod]標籤,來表示Unity容器裝載Mp3Player對象時將自動執行個體化所依賴的對象(即Song對象),然後注入到Mp3Player的Init方法裡 (執行該方法)。
即這裡主要做兩個操作:
1. Song song = new Song();
2. this.mSong = song;
注入到已存在的對象執行個體
用Resolve方法來擷取已存在的對象執行個體時不會做 Property Injection,因為該對象的建立沒受到 Unity 容器的任何影響。可以使用BuildUp方法來強制實現 Property Injection。
關於BuildUp方法可參考:
Unity Application Block 1.0系列(5): 使用BuildUp讓對象執行個體也支援依賴注入
結束語
使用 Method Call Injection 需要特別注意不要有循環參考,否則可能會導致應用程式出錯,至於循環參考的具體說明會有專門一篇文章介紹。
作者:Inrie (洪曉軍)
出處:http://www.cnblogs.com/inrie