/src/LinFu.IoC/Configuration/FluentInterfaces/UsingLambda.cs

http://github.com/philiplaureano/LinFu · C# · 138 lines · 60 code · 14 blank · 64 comment · 0 complexity · 9875d84bc2452b9a35e09094a63fbcb0 MD5 · raw file

  1. using System;
  2. using LinFu.IoC.Interfaces;
  3. namespace LinFu.IoC.Configuration
  4. {
  5. /// <summary>
  6. /// Represents a fluent class that creates
  7. /// a factory method that will be used
  8. /// in instantiating a specific service instance.
  9. /// </summary>
  10. /// <typeparam name="TService">The service type being instantiated.</typeparam>
  11. internal class UsingLambda<TService> : IUsingLambda<TService>
  12. {
  13. private readonly InjectionContext<TService> _context;
  14. /// <summary>
  15. /// Initializes the class using the given <paramref name="context" />.
  16. /// </summary>
  17. /// <param name="context">
  18. /// the <c>internal</c> context class that will be used to
  19. /// incrementally build enough information to inject a specific
  20. /// <see cref="IFactory{T}" /> instance into a container.
  21. /// </param>
  22. internal UsingLambda(InjectionContext<TService> context)
  23. {
  24. _context = context;
  25. }
  26. /// <summary>
  27. /// Creates a service instance using the
  28. /// concrete <typeparamref name="TConcrete" /> type
  29. /// as the implementation for the <typeparamref name="TService" />
  30. /// type.
  31. /// </summary>
  32. /// <typeparam name="TConcrete">
  33. /// The concrete implementation that implements <typeparamref name="TService" />. This class
  34. /// must have a default constructor.
  35. /// </typeparam>
  36. /// <returns>
  37. /// A non-null <see cref="IGenerateFactory{T}" /> instance that will be used to create a factory and add it to a
  38. /// specific container.
  39. /// </returns>
  40. public IGenerateFactory<TService> Using<TConcrete>() where TConcrete : TService
  41. {
  42. // Let the container decide which constructor should be used at runtime
  43. Func<IFactoryRequest, TService> factoryMethod = request =>
  44. {
  45. var container = request.Container;
  46. return
  47. (TService)
  48. container.AutoCreate(typeof(TConcrete),
  49. request.Arguments);
  50. };
  51. var context = new InjectionContext<TService>
  52. {
  53. ServiceName = _context.ServiceName,
  54. Container = _context.Container,
  55. FactoryMethod = factoryMethod
  56. };
  57. return new GenerateFactory<TService>(context);
  58. }
  59. /// <summary>
  60. /// Creates a service instance using the
  61. /// <paramref name="factoryMethod" /> to
  62. /// instantiate the service instance
  63. /// with a particular factory type.
  64. /// </summary>
  65. /// <seealso cref="IGenerateFactory{T}" />
  66. /// <param name="factoryMethod">The factory method that will be used to instantiate the actual service instance.</param>
  67. /// <returns>
  68. /// A non-null <see cref="IGenerateFactory{T}" /> instance that will be used to create a factory and add it to a
  69. /// specific container.
  70. /// </returns>
  71. public IGenerateFactory<TService> Using(Func<IServiceContainer, object[], TService> factoryMethod)
  72. {
  73. Func<IFactoryRequest, TService> adapter =
  74. request => factoryMethod(request.Container, request.Arguments);
  75. var context = new InjectionContext<TService>
  76. {
  77. Container = _context.Container,
  78. FactoryMethod = adapter,
  79. ServiceName = _context.ServiceName
  80. };
  81. return new GenerateFactory<TService>(context);
  82. }
  83. /// <summary>
  84. /// Creates a service instance using the
  85. /// <paramref name="factoryMethod" /> to
  86. /// instantiate the service instance
  87. /// with a particular factory type.
  88. /// </summary>
  89. /// <seealso cref="IGenerateFactory{T}" />
  90. /// <param name="factoryMethod">The factory method that will be used to instantiate the actual service instance.</param>
  91. /// <returns>
  92. /// A non-null <see cref="IGenerateFactory{T}" /> instance that will be used to create a factory and add it to a
  93. /// specific container.
  94. /// </returns>
  95. public IGenerateFactory<TService> Using(Func<IServiceContainer, TService> factoryMethod)
  96. {
  97. Func<IFactoryRequest, TService> adapter =
  98. request => factoryMethod(request.Container);
  99. var context = new InjectionContext<TService>
  100. {
  101. Container = _context.Container,
  102. FactoryMethod = adapter,
  103. ServiceName = _context.ServiceName
  104. };
  105. return new GenerateFactory<TService>(context);
  106. }
  107. /// <summary>
  108. /// Creates a service instance using the
  109. /// <paramref name="factoryMethod" /> to
  110. /// instantiate the service instance
  111. /// with a particular factory type.
  112. /// </summary>
  113. /// <param name="factoryMethod">The factory method that will be used to instantiate the actual service instance.</param>
  114. /// <returns>
  115. /// A non-null <see cref="IGenerateFactory{T}" /> instance that will be used to create a factory and add it to a
  116. /// specific container.
  117. /// </returns>
  118. public IGenerateFactory<TService> Using(Func<TService> factoryMethod)
  119. {
  120. Func<IServiceContainer, object[], TService> adapter = (container, arguments) => factoryMethod();
  121. return Using(adapter);
  122. }
  123. }
  124. }