PageRenderTime 36ms CodeModel.GetById 31ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 1ms

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