/src/LinFu.IoC/Factories/SingletonFactory.cs
C# | 69 lines | 30 code | 8 blank | 31 comment | 4 complexity | 7f7b13c0a6b0472884dbce59644d8809 MD5 | raw file
1using System; 2using System.Collections.Generic; 3using LinFu.IoC.Interfaces; 4 5namespace LinFu.IoC.Factories 6{ 7 /// <summary> 8 /// A factory that creates Singletons. Each service that this factory creates will only be created once per concrete 9 /// type. 10 /// </summary> 11 /// <typeparam name="T">The type of service to instantiate.</typeparam> 12 public class SingletonFactory<T> : BaseFactory<T> 13 { 14 private static readonly Dictionary<object, T> _instances = new Dictionary<object, T>(); 15 16 private static readonly object _lock = new object(); 17 private readonly Func<IFactoryRequest, T> _createInstance; 18 19 /// <summary> 20 /// Initializes the factory class using the <paramref name="createInstance" /> 21 /// parameter as a factory delegate. 22 /// </summary> 23 /// <example> 24 /// The following is an example of initializing a <c>SingletonFactory<T></c> 25 /// type: 26 /// <code> 27 /// // Define the factory delegate 28 /// Func<IFactoryRequest, ISomeService> createService = container=>new SomeServiceImplementation(); 29 /// 30 /// // Create the factory 31 /// var factory = new SingletonFactory<ISomeService>(createService); 32 /// 33 /// // Use the service instance 34 /// var service = factory.CreateInstance(null); 35 /// 36 /// // ... 37 /// </code> 38 /// </example> 39 /// <param name="createInstance">The delegate that will be used to create each new service instance.</param> 40 public SingletonFactory(Func<IFactoryRequest, T> createInstance) 41 { 42 _createInstance = createInstance; 43 } 44 45 /// <summary> 46 /// A method that creates a service instance as a singleton. 47 /// </summary> 48 /// <param name="request">The <see cref="IFactoryRequest" /> instance that describes the requested service.</param> 49 /// <returns>A service instance as a singleton.</returns> 50 public override T CreateInstance(IFactoryRequest request) 51 { 52 var key = new {request.ServiceName, request.ServiceType, request.Container}; 53 54 if (_instances.ContainsKey(key)) 55 return _instances[key]; 56 57 lock (_lock) 58 { 59 if (_instances.ContainsKey(key)) 60 return _instances[key]; 61 62 var result = _createInstance(request); 63 if (result != null) _instances[key] = result; 64 } 65 66 return _instances[key]; 67 } 68 } 69}