/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

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