什麼情況下使用Method CallInjection
當實例化父對象時也能自動實例化所依賴的對象
通過簡單的方式使得很容易做到在代碼中查看每個類所依賴的項
父對象有很多相互之間有關聯關系的構造器,導致在調試和維護時很不方便
父對象包含有很多參數構造器,特別是參數類型相似的只能通過參數的位置來辨別的
隱藏依賴的對象,不作為屬性暴露出去
通過修改依賴對象的代碼來控制哪些對象可以被注入,而不用改動父對象或應用程序
准備工作
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方法來獲取已存在的對象實例時不會做PropertyInjection,因為該對象的創建沒受到 Unity 容器的任何影響。可以使用BuildUp方法來強制實現 PropertyInjection。
關於BuildUp方法可參考:
Unity Application Block 1.0系列(5): 使用BuildUp讓對象實例也支持依賴注入
結束語
使用Method CallInjection 需要特別注意不要有循環引用,否則可能會導致應用程序出錯,至於循環引用的具體說明會有專門一篇文章介紹。