PageRenderTime 5ms CodeModel.GetById 2ms app.highlight 1ms RepoModel.GetById 1ms app.codeStats 0ms

/src/LinFu.IoC/Factories/SingletonFactory.cs

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