/src/LinFu.IoC/Configuration/FluentInterfaces/UsingLambda.cs
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}