背景
框架开发中,经常会用到“单例模式”,但是传统的单例模式不支持多态和运行时变化,在关注测试的今天,这种模式是不可行的。为了应对这种情况,微软又提供了另外一种模式,暂且将其称为“动态单例模式”。 我也想统一我的框架对单例的使用模式,因此就写了这篇文章。
Microsoft.Practices.ServiceLocation 核心代码
看完代码,如何使用这种模式就不用我多介绍了。
IServiceLocator
View Code
1 using System; 2 using System.Collections.Generic; 3 4 namespace Microsoft.Practices.ServiceLocation 5 { 6 /// <summary> 7 /// The generic Service Locator interface. This interface is used 8 /// to retrieve services (instances identified by type and optional 9 /// name) from a container. 10 /// </summary> 11 public interface IServiceLocator : IServiceProvider 12 { 13 /// <summary> 14 /// Get an instance of the given <paramref name="serviceType"/>. 15 /// </summary> 16 /// <param name="serviceType">Type of object requested.</param> 17 /// <exception cref="ActivationException">if there is an error resolving 18 /// the service instance.</exception> 19 /// <returns>The requested service instance.</returns> 20 object GetInstance(Type serviceType); 21 22 /// <summary> 23 /// Get an instance of the given named <paramref name="serviceType"/>. 24 /// </summary> 25 /// <param name="serviceType">Type of object requested.</param> 26 /// <param name="key">Name the object was registered with.</param> 27 /// <exception cref="ActivationException">if there is an error resolving 28 /// the service instance.</exception> 29 /// <returns>The requested service instance.</returns> 30 object GetInstance(Type serviceType, string key); 31 32 /// <summary> 33 /// Get all instances of the given <paramref name="serviceType"/> currently 34 /// registered in the container. 35 /// </summary> 36 /// <param name="serviceType">Type of object requested.</param> 37 /// <exception cref="ActivationException">if there is are errors resolving 38 /// the service instance.</exception> 39 /// <returns>A sequence of instances of the requested <paramref name="serviceType"/>.</returns> 40 IEnumerable<object> GetAllInstances(Type serviceType); 41 42 /// <summary> 43 /// Get an instance of the given <typeparamref name="TService"/>. 44 /// </summary> 45 /// <typeparam name="TService">Type of object requested.</typeparam> 46 /// <exception cref="ActivationException">if there is are errors resolving 47 /// the service instance.</exception> 48 /// <returns>The requested service instance.</returns> 49 TService GetInstance<TService>(); 50 51 /// <summary> 52 /// Get an instance of the given named <typeparamref name="TService"/>. 53 /// </summary> 54 /// <typeparam name="TService">Type of object requested.</typeparam> 55 /// <param name="key">Name the object was registered with.</param> 56 /// <exception cref="ActivationException">if there is are errors resolving 57 /// the service instance.</exception> 58 /// <returns>The requested service instance.</returns> 59 TService GetInstance<TService>(string key); 60 61 /// <summary> 62 /// Get all instances of the given <typeparamref name="TService"/> currently 63 /// registered in the container. 64 /// </summary> 65 /// <typeparam name="TService">Type of object requested.</typeparam> 66 /// <exception cref="ActivationException">if there is are errors resolving 67 /// the service instance.</exception> 68 /// <returns>A sequence of instances of the requested <typeparamref name="TService"/>.</returns> 69 IEnumerable<TService> GetAllInstances<TService>(); 70 } 71 }
ServiceLocatorProvider
View Code
1 namespace Microsoft.Practices.ServiceLocation 2 { 3 /// <summary> 4 /// This delegate type is used to provide a method that will 5 /// return the current container. Used with the <see cref="ServiceLocator"/> 6 /// static accessor class. 7 /// </summary> 8 /// <returns>An <see cref="IServiceLocator"/>.</returns> 9 public delegate IServiceLocator ServiceLocatorProvider(); 10 }
ServiceLocator
View Code
1 namespace Microsoft.Practices.ServiceLocation 2 { 3 /// <summary> 4 /// This class provides the ambient container for this application. If your 5 /// framework defines such an ambient container, use ServiceLocator.Current 6 /// to get it. 7 /// </summary> 8 public static class ServiceLocator 9 { 10 private static ServiceLocatorProvider currentProvider; 11 12 /// <summary> 13 /// The current ambient container. 14 /// </summary> 15 public static IServiceLocator Current 16 { 17 get { return currentProvider(); } 18 } 19 20 /// <summary> 21 /// Set the delegate that is used to retrieve the current container. 22 /// </summary> 23 /// <param name="newProvider">Delegate that, when called, will return 24 /// the current ambient container.</param> 25 public static void SetLocatorProvider(ServiceLocatorProvider newProvider) 26 { 27 currentProvider = newProvider; 28 } 29 } 30 }
动态单例模式的优点
- 支持多态。
- 运行时可变。
- 支持其它级别范围的单例,如:请求级、线程级和会话级等。
- 支持对象池。
备注
Microsoft.Practices.ServiceLocation下载地址:http://commonservicelocator.codeplex.com/。