PageRenderTime 31ms CodeModel.GetById 26ms app.highlight 2ms RepoModel.GetById 2ms app.codeStats 0ms

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

http://github.com/philiplaureano/LinFu
C# | 98 lines | 44 code | 13 blank | 41 comment | 5 complexity | 9ec6cfae756d6ba122d1c293d7f8d0a3 MD5 | raw file
 1using System;
 2using System.Collections.Generic;
 3using System.Diagnostics;
 4using System.Reflection;
 5using LinFu.IoC.Configuration.Interfaces;
 6using LinFu.IoC.Interfaces;
 7
 8namespace LinFu.IoC.Configuration
 9{
10    /// <summary>
11    ///     Represents a class that can choose a member that best matches
12    ///     the services currently available in a given <see cref="IServiceContainer" /> instance.
13    /// </summary>
14    /// <typeparam name="TMember">The member type that will be searched.</typeparam>
15    public abstract class MemberResolver<TMember> : IMemberResolver<TMember>
16        where TMember : MethodBase
17    {
18        private readonly Func<IServiceContainer, IMethodFinder<TMember>> _getFinder;
19
20        /// <summary>
21        ///     The default constructor for the <see cref="MemberResolver{TMember}" /> class.
22        /// </summary>
23        protected MemberResolver()
24        {
25            _getFinder = container => container.GetService<IMethodFinder<TMember>>();
26        }
27
28        /// <summary>
29        ///     Initializes the class with a <paramref name="getFinder">functor</paramref>
30        ///     that will be used to instantiate the method finder that will be used in the search.
31        /// </summary>
32        /// <param name="getFinder">The functor that will be used to instantiate the method finder.</param>
33        protected MemberResolver(Func<IServiceContainer, IMethodFinder<TMember>> getFinder)
34        {
35            _getFinder = getFinder;
36        }
37
38
39        /// <summary>
40        ///     Uses the <paramref name="container" /> to determine which member to use from
41        ///     the <paramref name="concreteType">concrete type</paramref>.
42        /// </summary>
43        /// <param name="concreteType">The target type.</param>
44        /// <param name="container">The container that contains the member values that will be used to invoke the members.</param>
45        /// <param name="finderContext">The <see cref="IMethodFinderContext" /> that describes the target method.</param>
46        /// <returns>A member instance if a match is found; otherwise, it will return <c>null</c>.</returns>
47        public TMember ResolveFrom(Type concreteType, IServiceContainer container,
48            IMethodFinderContext finderContext)
49        {
50            var constructors = GetMembers(concreteType);
51            if (constructors == null)
52                return null;
53
54            var resolver = GetMethodFinder(container);
55            var bestMatch = resolver.GetBestMatch(constructors, finderContext);
56
57            // If all else fails, find the
58            // default constructor and use it as the
59            // best match by default
60            if (bestMatch == null)
61            {
62                var defaultResult = GetDefaultResult(concreteType);
63
64                bestMatch = defaultResult;
65            }
66
67            Debug.Assert(bestMatch != null);
68            return bestMatch;
69        }
70
71
72        /// <summary>
73        ///     Determines the <see cref="IMethodFinder{T}" /> that will be used
74        ///     in the method search.
75        /// </summary>
76        /// <param name="container"></param>
77        /// <returns></returns>
78        protected virtual IMethodFinder<TMember> GetMethodFinder(IServiceContainer container)
79        {
80            return _getFinder(container);
81        }
82
83        /// <summary>
84        ///     The method used to retrieve the default result if no
85        ///     other alternative is found.
86        /// </summary>
87        /// <param name="concreteType">The target type that contains the default member.</param>
88        /// <returns>The default member result.</returns>
89        protected abstract TMember GetDefaultResult(Type concreteType);
90
91        /// <summary>
92        ///     Lists the members associated with the <paramref name="concreteType" />.
93        /// </summary>
94        /// <param name="concreteType">The target type that contains the type members.</param>
95        /// <returns>A list of members that belong to the concrete type.</returns>
96        protected abstract IEnumerable<TMember> GetMembers(Type concreteType);
97    }
98}