PageRenderTime 142ms CodeModel.GetById 70ms app.highlight 4ms RepoModel.GetById 66ms app.codeStats 1ms

/src/LinFu.IoC/Configuration/Resolvers/ConstructorArgumentResolver.cs

http://github.com/philiplaureano/LinFu
C# | 87 lines | 44 code | 13 blank | 30 comment | 3 complexity | 80b87dea903b61188159f9cc0c269536 MD5 | raw file
 1using System.Collections.Generic;
 2using System.Linq;
 3using System.Reflection;
 4using LinFu.IoC.Configuration.Interfaces;
 5using LinFu.IoC.Interfaces;
 6
 7namespace LinFu.IoC.Configuration.Resolvers
 8{
 9    /// <summary>
10    ///     Represents a class that determines the method arguments that should be used for a given constructor.
11    /// </summary>
12    public class ConstructorArgumentResolver : IConstructorArgumentResolver, IInitialize
13    {
14        private IArgumentResolver _argumentResolver;
15
16
17        /// <summary>
18        ///     Determines the parameter values that should be used for a given constructor.
19        /// </summary>
20        /// <param name="constructor">The target constructor.</param>
21        /// <param name="container">The host container instance.</param>
22        /// <param name="additionalArguments">
23        ///     The list of additional arguments that should be combined with the arguments from the
24        ///     container.
25        /// </param>
26        /// <returns>A list of arguments that will be used for the given constructor.</returns>
27        public object[] GetConstructorArguments(ConstructorInfo constructor, IServiceContainer container,
28            object[] additionalArguments)
29        {
30            var parameterTypes = GetMissingParameterTypes(constructor, additionalArguments);
31
32            // Generate the arguments for the target constructor
33            return _argumentResolver.ResolveFrom(parameterTypes, container,
34                additionalArguments);
35        }
36
37
38        /// <summary>
39        ///     Initializes the class with the default services.
40        /// </summary>
41        /// <param name="container">The target service container.</param>
42        public void Initialize(IServiceContainer container)
43        {
44            _argumentResolver = container.GetService<IArgumentResolver>();
45        }
46
47
48        /// <summary>
49        ///     Determines which parameter types need to be supplied to invoke a particular
50        ///     <paramref name="constructor" />  instance.
51        /// </summary>
52        /// <param name="constructor">The target constructor.</param>
53        /// <param name="additionalArguments">The additional arguments that will be used to invoke the constructor.</param>
54        /// <returns>The list of parameter types that are still missing parameter values.</returns>
55        private static IEnumerable<INamedType> GetMissingParameterTypes(ConstructorInfo constructor,
56            IEnumerable<object> additionalArguments)
57        {
58            var parameters = from p in constructor.GetParameters()
59                select p;
60
61            // Determine which parameters need to 
62            // be supplied by the container
63            var parameterTypes = new List<INamedType>();
64            var argumentCount = additionalArguments.Count();
65            if (additionalArguments != null && argumentCount > 0)
66            {
67                // Supply parameter values for the
68                // parameters that weren't supplied by the
69                // additionalArguments
70                var parameterCount = parameters.Count();
71                var maxIndex = parameterCount - argumentCount;
72                var targetParameters = from param in parameters.Where(p => p.Position < maxIndex)
73                    select new NamedType(param) as INamedType;
74
75                parameterTypes.AddRange(targetParameters);
76                return parameterTypes;
77            }
78
79            var results = from param in parameters
80                select new NamedType(param) as INamedType;
81
82            parameterTypes.AddRange(results);
83
84            return parameterTypes;
85        }
86    }
87}