public ConstructorDiscoveryFactory()
 {
     _constructor = ConstructorDiscovery.GetBestConstructor(typeof(TTarget), new[] { typeof(TArg) });
     if (_constructor == null)
     {
         throw new InvalidOperationException("The type " + typeof(TTarget).FullName + "Has no valid constructors");
     }
 }
        private static List <ScoredConstructor> GetConstructorsByScore(ConstructorDiscoveryContext context)
        {
            var constructors = context.TargetType.GetConstructors(BindingFlags.Public | BindingFlags.Instance);
            var scoredList   = new List <ScoredConstructor>();

            foreach (var constructor in constructors)
            {
                ScoredConstructor scored = ScoreConstructor(constructor, context);
                scoredList.Add(scored);
            }
            return(scoredList);
        }
        private static ScoredConstructor ScoreConstructor(ConstructorInfo constructor, ConstructorDiscoveryContext context)
        {
            if (constructor.IsPrivate)
            {
                return(ScoredConstructor.Unusable(constructor));
            }

            // parameters are the defined formal parameters of the constructor
            // arguments are the values and object references provided by the caller
            var parameters = constructor.GetParameters();

            if (parameters.Length == 0)
            {
                return(ScoredConstructor.Parameterless(constructor));
            }

            int         score         = 0;
            List <bool> usedArguments = context.ArgumentTypes.Select(t => false).ToList();
            var         argumentMap   = new Dictionary <int, int>();

            for (int paramIdx = 0; paramIdx < parameters.Length; paramIdx++)
            {
                var parameter     = parameters[paramIdx];
                int foundScore    = -1;
                var parameterType = parameter.ParameterType;
                for (int argIdx = 0; argIdx < context.ArgumentTypes.Count; argIdx++)
                {
                    if (usedArguments[argIdx])
                    {
                        continue;
                    }
                    var argType = context.ArgumentTypes[argIdx];
                    foundScore = ScoreTypeMatch(argType, parameterType);
                    if (foundScore >= 0)
                    {
                        usedArguments[argIdx] = true;
                        argumentMap.Add(paramIdx, argIdx);
                        score += foundScore;
                        break;
                    }
                }
                if (foundScore < 0)
                {
                    return(ScoredConstructor.Unusable(constructor));
                }
            }

            return(new ScoredConstructor(score, constructor, argumentMap));
        }