internal ConstructorData GetConstructorData(IList<ConstructorInfo> constructors, Arguments args) { /* 0: No Constructors : Throw Ex 1: Only Default Constructor, No Arguments : Invoke() 2: Only Default Constructor, Arguments supplied : Invoke() 3: Onlt Parameterised, No Arguments : Throw Ex() 4: Only Parameterised, Constructors with all args = 0 : Throw Ex 5: Only Parameterised, Constructors with exact args : Invoke() 6: Only Parameterised, Constructors with all args, registry cannot fill remainder : Throw Ex 7: Only Parameterised, Constructors with all args, registry can fill remainder : Invoke() 8: Mixed Constructors, No Arguments : Invoke() 9: Mixed Constructors, Constructors with all args = 0 : Throw Ex 10: Mixed Constructors, Constructors with exact args : Invoke() 11: Mixed Constructors, Constructors with all args, registry cannot fill remainder : Throw Ex 12: Mixed Constructors, Constructors with all args, registry can fill remainder : Invoke() */ //none if (constructors.Count == 0) { throw new ConstructorException(); } //only Default if (constructors.All(c => c.GetParameters().Count() == 0)) { //1 if (args.Count != 0) { throw new ConstructorException(); } //2 return new ConstructorData(constructors.First()); } //Only Parameterised if (constructors.All(c => c.GetParameters().Count() > 0)) { //3 if (args.Count == 0) { throw new ConstructorException(); } //4 if (!constructors.Any(c => args.All(a => c.GetParameters().Contains(a)))) { throw new ConstructorException(); } var withAll = constructors.Where(c => args.All(a => c.GetParameters().Contains(a))); var exact = withAll.Where(c => c.GetParameters().Count() == args.Count); //5 if (exact.Count() > 0) { var best = GetBestMatch(exact, args, null); return new ConstructorData(best.Constructor, best.Arguments); } //6 var unmatchedArgs = GetUnmatchedArgs(withAll, args); if (!unmatchedArgs.Any(u => _registry.ContainsAll(u.Value.Select(p => p.ParameterType)))) { throw new ConstructorException(); } //7 var bestMatch = GetBestMatch(exact, args, unmatchedArgs); return new ConstructorData(bestMatch.Constructor , bestMatch.Arguments); } //mixed if (constructors.Any(c => c.GetParameters().Count() > 0) && constructors.Any(c => c.GetParameters().Count() == 0)) { //8 if (args.Count == 0) { var ctor = constructors.First(c => c.GetParameters().Count() == 0); return new ConstructorData(ctor); } //9 if (!constructors.Any(c => args.All(a => c.GetParameters().Contains(a)))) { throw new ConstructorException(); } var withAll = constructors.Where(c => args.All(a => c.GetParameters().Contains(a))); var exact = withAll.Where(c => c.GetParameters().Count() == args.Count); //10 if (exact.Count() > 0) { var best = GetBestMatch(exact, args, new Dictionary<ConstructorInfo, IList<ParameterInfo>>() ); return new ConstructorData(best.Constructor, best.Arguments); } //11 var unmatchedArgs = GetUnmatchedArgs(withAll, args); if (!unmatchedArgs.Any(u => _registry.ContainsAll(u.Value.Select(p => p.ParameterType)))) { throw new ConstructorException(); } //12 var bestMatch = GetBestMatch(exact, args, unmatchedArgs); return new ConstructorData(bestMatch.Constructor, bestMatch.Arguments); } throw new ConstructorException(); }