/src/UnitTests/IOC/FluentExtensionTests.Implementation.cs

http://github.com/philiplaureano/LinFu · C# · 125 lines · 87 code · 22 blank · 16 comment · 0 complexity · 18de321bbe9dc6774168b16560af7ddb MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using LinFu.IoC;
  4. using LinFu.IoC.Configuration;
  5. using LinFu.IoC.Interfaces;
  6. using Xunit;
  7. using SampleLibrary;
  8. namespace LinFu.UnitTests.IOC
  9. {
  10. public partial class FluentExtensionTests
  11. {
  12. private static void TestOncePerThread(string serviceName,
  13. Func<IUsingLambda<ISampleService>, IGenerateFactory<ISampleService>>
  14. doInject)
  15. {
  16. Test(serviceName, factory => factory.OncePerThread(), doInject, VerifyOncePerThread);
  17. }
  18. private static void TestSingleton(string serviceName,
  19. Func<IUsingLambda<ISampleService>, IGenerateFactory<ISampleService>> doInject)
  20. {
  21. Test(serviceName, factory => factory.AsSingleton(),
  22. doInject, VerifySingleton);
  23. }
  24. private static void TestOncePerRequest(string serviceName,
  25. Func<IUsingLambda<ISampleService>, IGenerateFactory<ISampleService>>
  26. doInject)
  27. {
  28. Test(serviceName, factory => factory.OncePerRequest(),
  29. doInject, VerifyOncePerRequest);
  30. }
  31. private static bool VerifySingleton(string serviceName, IServiceContainer container)
  32. {
  33. // The container must be able to create the
  34. // ISampleService instance
  35. Assert.True(container.Contains(serviceName, typeof(ISampleService)));
  36. // The container should return the singleton
  37. var first = container.GetService<ISampleService>(serviceName);
  38. var second = container.GetService<ISampleService>(serviceName);
  39. Assert.Same(first, second);
  40. return true;
  41. }
  42. private static bool VerifyOncePerThread(string serviceName, IServiceContainer container)
  43. {
  44. var results = new List<ISampleService>();
  45. Func<ISampleService> createService = () =>
  46. {
  47. var result = container.GetService<ISampleService>(serviceName);
  48. lock (results)
  49. {
  50. results.Add(result);
  51. }
  52. return null;
  53. };
  54. Assert.True(container.Contains(serviceName, typeof(ISampleService)));
  55. // Create the other instance from another thread
  56. var asyncResult = createService.BeginInvoke(null, null);
  57. // Two instances created within the same thread must be
  58. // the same
  59. var first = container.GetService<ISampleService>(serviceName);
  60. var second = container.GetService<ISampleService>(serviceName);
  61. Assert.NotNull(first);
  62. Assert.Same(first, second);
  63. // Wait for the other thread to finish executing
  64. createService.EndInvoke(asyncResult);
  65. Assert.True(results.Count > 0);
  66. // The service instance created in the other thread
  67. // must be unique
  68. Assert.NotNull(results[0]);
  69. Assert.NotSame(first, results[0]);
  70. // NOTE: The return value will be ignored
  71. return true;
  72. }
  73. private static bool VerifyOncePerRequest(string serviceName, IServiceContainer container)
  74. {
  75. // The container must be able to create an
  76. // ISampleService instance
  77. Assert.True(container.Contains(serviceName, typeof(ISampleService)), "Service not found!");
  78. // Both instances must be unique
  79. var first = container.GetService<ISampleService>(serviceName);
  80. var second = container.GetService<ISampleService>(serviceName);
  81. Assert.NotSame(first, second);
  82. return true;
  83. }
  84. private static void Inject(string serviceName, Action<IGenerateFactory<ISampleService>> usingFactory,
  85. Func<IUsingLambda<ISampleService>, IGenerateFactory<ISampleService>> doInject,
  86. ServiceContainer container)
  87. {
  88. // HACK: Condense the fluent statements into a single,
  89. // reusable line of code
  90. usingFactory(doInject(container.Inject<ISampleService>(serviceName)));
  91. }
  92. private static void Test(string serviceName, Action<IGenerateFactory<ISampleService>> usingFactory,
  93. Func<IUsingLambda<ISampleService>, IGenerateFactory<ISampleService>> doInject,
  94. Func<string, IServiceContainer, bool> verifyResult)
  95. {
  96. var container = new ServiceContainer();
  97. // HACK: Manually inject the required services into the container
  98. container.AddDefaultServices();
  99. Inject(serviceName, usingFactory, doInject, container);
  100. verifyResult(serviceName, container);
  101. }
  102. }
  103. }