惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
J
Java Code Geeks
博客园 - 聂微东
量子位
C
Check Point Blog
T
The Blog of Author Tim Ferriss
T
Tailwind CSS Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
B
Blog
罗磊的独立博客
腾讯CDC
GbyAI
GbyAI
博客园 - 【当耐特】
A
About on SuperTechFans
M
MIT News - Artificial intelligence
U
Unit 42
D
Docker
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Y
Y Combinator Blog
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队

博客园 - Inrie

[原创]MongoDB、HandlerSocket和MySQL性能测试及其结果分析 [原创]HandlerSocket系列(三):性能及其性能优化 [原创]HandlerSocket系列(二):架构、特点及其应用场景 [原创]HandlerSocket系列(一):由来 SD2.0 2009大会一些感想 在Windows Server 2008集群上做Sql Server 2008集群 解决Azure Project中使用Asp.net MVC RC会让VS崩溃的补丁 [译]剖析ASP.Net MVC Application 让VS 2008也可以用Mobile Web Form 几个不错的WCF Tools ADO.NET Entity Framework Beta3的一些问题 善待你的眼睛-使用微软专为程序员设计的Consolas字体 [推荐]ASP.NET 应用程序的扩展策略 [翻译+推荐]你需要知道的:WCF、WF、ADO.NET SyncServices和ClickOnce 如何发布Ado.net Entity Framework EDM Unity Application Block 1.0系列文章 Unity Application Block 1.0系列(6): 杜绝循环引用 Unity Application Block 1.0系列(5): 使用BuildUp让已存在对象实例也支持依赖注入 Unity Application Block 1.0系列(4): 方法调用注入(Method Call Injection )
Unity Application Block 1.0系列(7): Lifetime Managers
Inrie · 2008-04-20 · via 博客园 - Inrie

Unity使用继承于 LifetimeManager 基类的类去控制怎样存放到对象实例的引用和容器怎样销毁这些实例,也就是说Unity基于具体的Lifetime Manager 类去管理对象的创建和销毁。

目前Unity中提供两个Lifetime Manager类可供我们直接使用,当然你也可以实现自己的Lifetime Manager类。

1. ContainerControlledLifetimeManager

Unity保存一个指向对象实例的引用。通过Unity容器为同一个类型或对象获取对象实例时,每次获取到的都是同一个实例。也就是说实现了对象单例模式。默认情况下,RegisterInstance方法使用该Lifetime Manager。


2. ExternallyControlledLifetimeManager Unity仅保存一个指向对象实例的弱引用。通过Unity容器为同一个类型或对象获取对象实例时,每次获取到的都是同一个实例。但是由于当对象创建完之后,容器没有对该对象的强引用,所以就可能出现当其他地方没有去强引用它时候,会被GC回收掉。

先看看一个接口和类,下面会用到

public interface IPlayer
{
    
void Play();
}
public class Mp3Player : IPlayer
{
    
public void Play()
    {
        Console.WriteLine(
"Playing Mp3");
    }
}


接下来通过在RegisterType和RegisterInstance时指定相应的Lifetime Manager来介绍Lifetime Manager的应用场景。

1. RegisterType

当用RegisterType注册映射关系时,如果没有指定LifetimeManager,默认是使用一个瞬态的Lifetime Manager。即每次通过Unity容器获取对象的实例时都会重新创建一个该实例,也就是说Unity容器不存在一个到该对象的引用。

看一个例子:

IUnityContainer container = new UnityContainer();

container.RegisterType

<IPlayer, Mp3Player>();

IPlayer player1 

= container.Resolve<IPlayer>();
Console.WriteLine(
string.Format("Player1 HashCode: {0}",player1.GetHashCode()));

IPlayer player2 

= container.Resolve<IPlayer>();
Console.WriteLine(
string.Format("Player2 HashCode: {0}",player2.GetHashCode()));

输出结果:

Unity 7-1.jpg

通过输出的player1和player2对象的HashCode值可以看出,player1和player2分别是Mp3Player类的不同实例。

那怎样实现单例模式呢?

要实现单例模式,容器需要保存一个指向对象实例的引用。通过在RegisterType时为它指定相应的Lifetime Manager可以实现单例模式,从上面对ContainerControlledLifetimeManager和ExternallyControlledLifetimeManager的介绍可以知道,这两个Lifetime Manager都可以支持单例模式。

修改上面的代码为:

IUnityContainer container = new UnityContainer();//这里指定使用ContainerControlledLifetimeManager对象
container.RegisterType<IPlayer, Mp3Player>(new ContainerControlledLifetimeManager());

IPlayer player1 

= container.Resolve<IPlayer>();
Console.WriteLine(
string.Format("Player1 HashCode: {0}",player1.GetHashCode()));

IPlayer player2 

= container.Resolve<IPlayer>();
Console.WriteLine(
string.Format("Player2 HashCode: {0}",player2.GetHashCode()));


看看输出:

Unity 7-2.jpg

通过输出结果可以看出,player1和player2对象为Mp3Player类的同一实例,指向同一内存地址。

2. RegisterInstance

当用RegisterInstance注册映射关系时,如果没有指定Lifetime Manager,默认是使用ContainerControlledLifetimeManager,即支持单例模式。

看个例子:

IUnityContainer container = new UnityContainer();

IPlayer mp3Player 

= new Mp3Player();
container.RegisterInstance
<IPlayer>(mp3Player);

IPlayer player1 

= container.Resolve<IPlayer>();
Console.WriteLine(
string.Format("Player1 HashCode: {0}", player1.GetHashCode()));

IPlayer player2 

= container.Resolve<IPlayer>();
Console.WriteLine(
string.Format("Player2 HashCode: {0}", player2.GetHashCode()));

看看输出:

Unity 7-3.jpg

通过输出结果可以看出,player1和player2对象为Mp3Player类的同一实例,指向同一内存地址。

作者:Inrie (洪晓军)
出处:http://www.cnblogs.com/inrie