IoC容器的对象生存期管理
如果你一直在使用IoC容器,你可能已经使用过了一些对象生存期管理模型(Object Lifetime Management)。通过对对象生存期的管理,将使对象的复用成为可能。同时其使容器可以控制如何创建和管理对象实例。
Unity提供的对象生存期管理模型是通过从抽象类LifetimeManager的派生类来完成。Unity将为每个类型的注册创建生存期管理器。每当UnityContainer需要创建一个新的对象实例时,将首先检测该对象类型的生存期管理器,是否已有一个对象实例可用。如果没有对象实例可用,则UnityContainer将基于配置的信息构造该对象实例并将该对象交予对象生存期管理器。
LifetimeManager
LifetimeManager是一个抽象类,其实现了ILifetimePolicy接口。该类被作为所有内置或自定义的生存期管理器的父类。它定义了3个方法: GetValue - 返回一个已经存储在生存期管理器中对象实例。 SetValue - 存储一个新对象实例到生存期管理器中。 RemoveValue - 从生存期管理器中将已存储的对象实例删除。UnityContainer的默认实现将不会调用此方法,但可在定制的容器扩展中调用。
Unity内置了6种生存期管理模型,其中有2种即负责对象实例的创建也负责对象实例的销毁(Disposing)。
"codetitle">复制代码 代码如下:
public interface IExample : IDisposable
{
void SayHello();
}
public class Example : IExample
{
private bool _disposed = false;
private readonly Guid _key = Guid.NewGuid();
public void SayHello()
{
if (_disposed)
{
throw new ObjectDisposedException("Example",
string.Format("{0} is already disposed!", _key));
}
Console.WriteLine("{0} says hello in thread {1}!", _key,
Thread.CurrentThread.ManagedThreadId);
}
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
}
}
}
TransientLifetimeManager
TransientLifetimeManager是Unity默认的生存期管理器。其内部的实现都为空,这就意味着每次容器都会创建和返回一个新的对象实例,当然容器也不负责存储和销毁该对象实例。
复制代码 代码如下:
private static void TestTransientLifetimeManager()
{
IExample example;
using (IUnityContainer container = new UnityContainer())
{
container.RegisterType(typeof(IExample), typeof(Example),
new TransientLifetimeManager());
// each one gets its own instance
container.Resolve<IExample>().SayHello();
example = container.Resolve<IExample>();
}
// container is disposed but Example instance still lives
// all previously created instances weren't disposed!
example.SayHello();
Console.ReadKey();
}
ContainerControlledLifetimeManager
ContainerControlledLifetimeManager将为UnityContainer及其子容器提供一个Singleton的注册类型对象实例。其只在第一次请求某注册类型时创建一个新的对象实例,该对象实例将被存储到生存期管理器中,并且一直被重用。当容器析构时,生存期管理器会调用RemoveValue将存储的对象销毁。
Singleton对象实例对应每个对象类型注册,如果同一对象类型注册多次,则将为每次注册创建单一的实例。
复制代码 代码如下:
private static void TestContainerControlledLifetimeManager()
{
IExample example;
using (IUnityContainer container = new UnityContainer())
{
container.RegisterType(typeof(IExample), typeof(Example),
new ContainerControlledLifetimeManager());
IUnityContainer firstSub = null;
IUnityContainer secondSub = null;
try
{
firstSub = container.CreateChildContainer();
secondSub = container.CreateChildContainer();
// all containers share same instance
// each resolve returns same instance
firstSub.Resolve<IExample>().SayHello();
// run one resolving in other thread and still receive same instance
Thread thread = new Thread(
() => secondSub.Resolve<IExample>().SayHello());
thread.Start();
container.Resolve<IExample>().SayHello();
example = container.Resolve<IExample>();
thread.Join();
}
finally
{
if (firstSub != null) firstSub.Dispose();
if (secondSub != null) secondSub.Dispose();
}
}
try
{
// exception - instance has been disposed with container
example.SayHello();
}
catch (ObjectDisposedException ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
HierarchicalLifetimeManager类衍生自ContainerControlledLifetimeManager,其继承了父类的所有行为。与父类的不同之处在于子容器中的生存期管理器行为。ContainerControlledLifetimeManager共享相同的对象实例,包括在子容器中。而HierarchicalLifetimeManager只在同一个容器内共享,每个子容器都有其单独的对象实例。
复制代码 代码如下:
private static void TestHierarchicalLifetimeManager()
{
IExample example;
using (IUnityContainer container = new UnityContainer())
{
container.RegisterType(typeof(IExample), typeof(Example),
new HierarchicalLifetimeManager());
IUnityContainer firstSub = null;
IUnityContainer secondSub = null;
try
{
firstSub = container.CreateChildContainer();
secondSub = container.CreateChildContainer();
// each subcontainer has its own instance
firstSub.Resolve<IExample>().SayHello();
secondSub.Resolve<IExample>().SayHello();
container.Resolve<IExample>().SayHello();
example = firstSub.Resolve<IExample>();
}
finally
{
if (firstSub != null) firstSub.Dispose();
if (secondSub != null) secondSub.Dispose();
}
}
try
{
// exception - instance has been disposed with container
example.SayHello();
}
catch (ObjectDisposedException ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
ExternallyControlledLifetimeManager
ExternallyControlledLifetimeManager中的对象实例的生存期限将有UnityContainer外部的实现控制。此生存期管理器内部直存储了所提供对象实例的一个WeakReference。所以如果UnityContainer容器外部实现中没有对该对象实例的强引用,则该对象实例将被GC回收。再次请求该对象类型实例时,将会创建新的对象实例。
复制代码 代码如下:
private static void TestExternallyControlledLifetimeManager()
{
IExample example;
using (IUnityContainer container = new UnityContainer())
{
container.RegisterType(typeof(IExample), typeof(Example),
new ExternallyControlledLifetimeManager());
// same instance is used in following
container.Resolve<IExample>().SayHello();
container.Resolve<IExample>().SayHello();
// run garbate collector. Stored Example instance will be released
// beacuse there is no reference for it and LifetimeManager holds
// only WeakReference
GC.Collect();
// object stored targeted by WeakReference was released
// new instance is created!
container.Resolve<IExample>().SayHello();
example = container.Resolve<IExample>();
}
example.SayHello();
Console.ReadKey();
}
这个结果证明强引用还存在,不知道为什么?如果你找到了原因,烦请告诉我,谢谢。
PerThreadLifetimeManager
PerThreadLifetimeManager模型提供“每线程单实例”功能。所有的对象实例在内部被存储在ThreadStatic的集合。容器并不跟踪对象实例的创建并且也不负责Dipose。
复制代码 代码如下:
private static void TestPerThreadLifetimeManager()
{
IExample example;
using (IUnityContainer container = new UnityContainer())
{
container.RegisterType(typeof(IExample), typeof(Example),
new PerThreadLifetimeManager());
Action<int> action = delegate(int sleep)
{
// both calls use same instance per thread
container.Resolve<IExample>().SayHello();
Thread.Sleep(sleep);
container.Resolve<IExample>().SayHello();
};
Thread thread1 = new Thread((a) => action.Invoke((int)a));
Thread thread2 = new Thread((a) => action.Invoke((int)a));
thread1.Start(50);
thread2.Start(50);
thread1.Join();
thread2.Join();
example = container.Resolve<IExample>();
}
example.SayHello();
Console.ReadKey();
}
PerResolveLifetimeManager
PerResolveLifetimeManager是Unity内置的一个特殊的模型。因为Unity使用单独的逻辑来处理注册类型的Per-Resolve生命期。每次请求Resolve一个类型对象时,UnityContainer都会创建并返回一个新的对象实例。
复制代码 代码如下:
private static void TestPerResolveLifetimeManager()
{
IExample example;
using (IUnityContainer container = new UnityContainer())
{
container.RegisterType(typeof(IExample), typeof(Example),
new PerResolveLifetimeManager());
container.Resolve<IExample>().SayHello();
container.Resolve<IExample>().SayHello();
example = container.Resolve<IExample>();
}
example.SayHello();
Console.ReadKey();
}
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]