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