PageRenderTime 29ms CodeModel.GetById 23ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

/src/LinFu.IoC/Factories/OncePerThreadFactory.cs

http://github.com/philiplaureano/LinFu
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&lt;T&gt;</c>
24        ///     type:
25        ///     <code>
26        ///     // Define the factory delegate
27        ///     Func&lt;IFactoryRequest, ISomeService&gt; createService = container=>new SomeServiceImplementation();
28        /// 
29        ///     // Create the factory
30        ///     var factory = new OncePerThreadFactory&lt;ISomeService&gt;(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}