Unity 学习笔记(3) -- 生命周期管理
2009-04-28 23:34
381 查看
Unity根据我们在注册类型的时候所指定的生命周期来管理注册类型的创建和解析。当我们在向容器中注册类型的时候,如果我们没有显式的指明该类型的生命周期管理器(下称:LifetimeManager),默认的情况下,容器会为我们注册的类型创建一个生命周期短暂的管理器。这样一来,当我们每次调用容器的Resolve方法或者ResolveAll方法,或者采用依赖机制注入实例到其他的类中的时候,容器都会为我们创建新的实例,并且容器不会保存对实例的引用。
容器的RegisterType函数包含多个支持泛型的重载,同时还包含了一一对应的非泛型重载。其中的重载函数,我们可以看到类似下面的声明:
1.ContainerControlledLifetimeManager:
容器负责管理注册类型的生命周期,并且注册类型的生命周期和容器一致。当离开容器的作用域范围时,容器会被销毁,同时其中的注册类型也会被销毁。或者,当容器被显式销毁时,其中的注册类型也同样被销毁。但是在容器有效的作用域范围中,当我们使用Resolve方法,或者使用ResolveAll方法获取我们的注册类型的时候,容器会在第一次调用时,创建实例,但是在后面的调用中,我们始终只会得到相同的实例。我们可以利用这种Manager来实现Singleton模式。
2.ExternallyControlledLifetimeManager:
和上一种方式类似,不过容器在不会保留对注册类型的强引用,而只是保留弱引用。也就是说,如果这个注册类型没有在其他地方被强引用的时候,那么这个注册类型可能会被GC给干掉。
3.PerThreadLifetimeManager:
容器保证在每个线程中返回同一个对象实例,那么在不同的线程中,得到的实例是不同的。
下面我们可以试验一下不同的LifetimeManager的效果
a.默认的情况,不显示的指明LifetimeManager
代码:
从结果我们可以看到,默认情况下不指定LifetimeManager的时候,每次我们获得的Instance其实不是同一个Instance.
b.使用ContainerControlledLifetimeManager
代码:
使用ContainerControlledLifetimeManager,在Container生命中期内,我们得到的Instance是同一个。
c.使用PerThreadLifetimeManager
代码:
容器的RegisterType函数包含多个支持泛型的重载,同时还包含了一一对应的非泛型重载。其中的重载函数,我们可以看到类似下面的声明:
RegisterType<TFrom,TTo>(LifetimeManagerlifetime).csharpcode,.csharpcodepre{font-size:small;color:black;font-family:consolas,"CourierNew",courier,monospace;background-color:#ffffff;/*white-space:pre;*/}.csharpcodepre{margin:0em;}.csharpcode.rem{color:#008000;}.csharpcode.kwrd{color:#0000ff;}.csharpcode.str{color:#006080;}.csharpcode.op{color:#0000c0;}.csharpcode.preproc{color:#cc6633;}.csharpcode.asp{background-color:#ffff00;}.csharpcode.html{color:#800000;}.csharpcode.attr{color:#ff0000;}.csharpcode.alt{background-color:#f4f4f4;width:100%;margin:0em;}.csharpcode.lnum{color:#606060;}参数中的LifetimeManager类型,就是用来控制注册类型生命周期的。Unity中提供了几个继承自LifetimeManager的类作为注册类型的生命周期管理器。在目前的Unity1.2版本中,共提供了3个LifetimeManager供我们直接在代码中调用。此外,我们也可以实现自己的LifetimeManager,不过必须实现LifetimeManager所必须的一些方法。
1.ContainerControlledLifetimeManager:
容器负责管理注册类型的生命周期,并且注册类型的生命周期和容器一致。当离开容器的作用域范围时,容器会被销毁,同时其中的注册类型也会被销毁。或者,当容器被显式销毁时,其中的注册类型也同样被销毁。但是在容器有效的作用域范围中,当我们使用Resolve方法,或者使用ResolveAll方法获取我们的注册类型的时候,容器会在第一次调用时,创建实例,但是在后面的调用中,我们始终只会得到相同的实例。我们可以利用这种Manager来实现Singleton模式。
2.ExternallyControlledLifetimeManager:
和上一种方式类似,不过容器在不会保留对注册类型的强引用,而只是保留弱引用。也就是说,如果这个注册类型没有在其他地方被强引用的时候,那么这个注册类型可能会被GC给干掉。
3.PerThreadLifetimeManager:
容器保证在每个线程中返回同一个对象实例,那么在不同的线程中,得到的实例是不同的。
下面我们可以试验一下不同的LifetimeManager的效果
a.默认的情况,不显示的指明LifetimeManager
代码:
namespaceUnityDemo
{
classProgram
{
staticvoidMain(string[]args)
{
IUnityContainercontainer=newUnityContainer();
container.RegisterType<INotify,EmailNotify>();
INotifynotify1=container.Resolve<INotify>();
INotifynotify2=container.Resolve<INotify>();
Console.WriteLine("notify1:"+notify1.GetHashCode());
Console.WriteLine("notify2:"+notify2.GetHashCode());
Console.ReadLine();
}
}
}.csharpcode,.csharpcodepre{font-size:small;color:black;font-family:consolas,"CourierNew",courier,monospace;background-color:#ffffff;/*white-space:pre;*/}.csharpcodepre{margin:0em;}.csharpcode.rem{color:#008000;}.csharpcode.kwrd{color:#0000ff;}.csharpcode.str{color:#006080;}.csharpcode.op{color:#0000c0;}.csharpcode.preproc{color:#cc6633;}.csharpcode.asp{background-color:#ffff00;}.csharpcode.html{color:#800000;}.csharpcode.attr{color:#ff0000;}.csharpcode.alt{background-color:#f4f4f4;width:100%;margin:0em;}.csharpcode.lnum{color:#606060;}运行结果:
从结果我们可以看到,默认情况下不指定LifetimeManager的时候,每次我们获得的Instance其实不是同一个Instance.
b.使用ContainerControlledLifetimeManager
代码:
namespaceUnityDemo
{
classProgram
{
staticvoidMain(string[]args)
{
IUnityContainercontainer=newUnityContainer();
container.RegisterType<INotify,EmailNotify>(newContainerControlledLifetimeManager());
INotifynotify1=container.Resolve<INotify>();
INotifynotify2=container.Resolve<INotify>();
Console.WriteLine("notify1:"+notify1.GetHashCode());
Console.WriteLine("notify2:"+notify2.GetHashCode());
Console.ReadLine();
}
}
}.csharpcode,.csharpcodepre{font-size:small;color:black;font-family:consolas,"CourierNew",courier,monospace;background-color:#ffffff;/*white-space:pre;*/}.csharpcodepre{margin:0em;}.csharpcode.rem{color:#008000;}.csharpcode.kwrd{color:#0000ff;}.csharpcode.str{color:#006080;}.csharpcode.op{color:#0000c0;}.csharpcode.preproc{color:#cc6633;}.csharpcode.asp{background-color:#ffff00;}.csharpcode.html{color:#800000;}.csharpcode.attr{color:#ff0000;}.csharpcode.alt{background-color:#f4f4f4;width:100%;margin:0em;}.csharpcode.lnum{color:#606060;}运行结果:
使用ContainerControlledLifetimeManager,在Container生命中期内,我们得到的Instance是同一个。
c.使用PerThreadLifetimeManager
代码:
namespaceUnityDemo
{
classProgram
{
staticvoidMain(string[]args)
{
IUnityContainercontainer=newUnityContainer();
container.RegisterType<INotify,EmailNotify>(newPerThreadLifetimeManager());
Threadthread1=newThread(newParameterizedThreadStart(ThreadProc1));
Threadthread2=newThread(newParameterizedThreadStart(ThreadProc2));
thread1.Start(container);
thread2.Start(container);
Console.ReadLine();
}
staticvoidThreadProc1(objectobj)
{
INotifynotify1=(objasIUnityContainer).Resolve<INotify>();
INotifynotify2=(objasIUnityContainer).Resolve<INotify>();
Console.WriteLine("ThreadProc1---notify1:"+notify1.GetHashCode());
Console.WriteLine("ThreadProc1---notify2:"+notify2.GetHashCode());
}
staticvoidThreadProc2(objectobj)
{
INotifynotify1=(objasIUnityContainer).Resolve<INotify>();
INotifynotify2=(objasIUnityContainer).Resolve<INotify>();
Console.WriteLine("ThreadProc2---notify1:"+notify1.GetHashCode());
Console.WriteLine("ThreadProc2---notify2:"+notify2.GetHashCode());
}
}
}
运行结果:
在结果中可以看到,同一个线程中连续两次获取到的是同一个Instance,而不同的线程中获取到的Instance不一样。
相关文章推荐
- Unity官方第一个人称射击游戏<恶魔射手>—学习笔记四(游戏中的管理)
- 1.4_Android Training 学习笔记_管理 Activity 的生命周期
- 第二章--第一节:软件的生命周期和配置管理(软件构造学习笔记)
- Unity3D笔记八 Unity生命周期及动画学习
- [原创]java WEB学习笔记94:Hibernate学习之路---session 的管理,Session 对象的生命周期与本地线程绑定
- Spring学习笔记(1):Bean的生命周期管理
- spring学习笔记整理--04(配置Spring管理的bean的作用域、生命周期)
- ITCAST视频-Spring学习笔记(Spring管理的Bean的生命周期)
- 10.Spring学习笔记_管理Bean的生命周期(by尚硅谷_佟刚)
- Spring学习笔记之管理Bean的生命周期
- 蓝鸥Unity入门脚本生命周期学习笔记
- spring2.5.6学习笔记七:Spring管理的Bean的生命周期
- Unity基础知识学习笔记二
- DB2 学习笔记 ——数据库管理
- Linux学习笔记之软件安装管理
- Unity Shader 学习笔记(十一) 混合纹理Shader实例
- 【Java学习-J.160406.0.6】笔记5-Linux基础-linux进程管理
- TeamForge学习笔记2-流程管理
- iphone学习笔记--应用程序生命周期