Unity Application Block 1.0系列(4): 方法调用注入(Method Call Injection )
什么情况下使用Method Call Injection
当实例化父对象时也能自动实例化所依赖的对象
通过简单的方式使得很容易做到在代码中查看每个类所依赖的项
父对象有很多相互之间有关联关系的构造器,导致在调试和维护时很不方便
父对象包含有很多参数构造器,特别是参数类型相似的只能通过参数的位置来辨别的
隐藏依赖的对象,不作为属性暴露出去
通过修改依赖对象的代码来控制哪些对象可以被注入,而不用改动父对象或应用程序
准备工作
{
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]标签:
public void Init(Song song)
{
this.mSong = song;
}
可以通过下面的方式来获取Mp3Player对象实例:
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 需要特别注意不要有循环引用,否则可能会导致应用程序出错,至于循环引用的具体说明会有专门一篇文章介绍。