程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Unity Application Block 1.0系列(7):Lifetime Managers

Unity Application Block 1.0系列(7):Lifetime Managers

編輯:關於.NET

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()));

輸出結果:

通過輸出的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()));

看看輸出:

通過輸出結果可以看出,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()));

看看輸出:

通過輸出結果可以看出,player1和player2對象為Mp3Player類的同一實例,指向同一內存地址。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved