Esempio n. 1
0
        public object create(Type type, List <object> constructorArgs)
        {
            var key = callKey(type, "<new>", constructorArgs);

            var activator = (ObjectActivator)Context.Cache.GetOrAdd(key, k => {
                var argsCount = constructorArgs?.Count ?? 0;

                var args  = constructorArgs;
                var ctors = type.GetConstructors()
                            .Where(x => x.GetParameters().Length == argsCount).ToArray();

                if (ctors.Length == 0)
                {
                    var argTypes = string.Join(",", args.Select(x => x?.GetType().Name ?? "null"));
                    throw new NotSupportedException($"Constructor {Context.DefaultMethods.typeQualifiedName(type)}({argTypes}) does not exist");
                }

                ConstructorInfo targetCtor = null;
                if (ctors.Length > 1)
                {
                    var candidates = 0;
                    foreach (var ctor in ctors)
                    {
                        var match = true;

                        var ctorParams = ctor.GetParameters();
                        if (args != null)
                        {
                            for (var i = 0; i < args.Count; i++)
                            {
                                var arg = args[i];
                                if (arg == null)
                                {
                                    continue;
                                }

                                match = ctorParams[i].ParameterType == arg.GetType();
                                if (!match)
                                {
                                    break;
                                }
                            }
                        }

                        if (match)
                        {
                            targetCtor = ctor;
                            candidates++;
                        }
                    }

                    if (targetCtor == null || candidates != 1)
                    {
                        var argTypes = args != null ? string.Join(",", args.Select(x => x?.GetType().Name ?? "null")) : "";
                        throw new NotSupportedException($"Could not resolve ambiguous constructor {Context.DefaultMethods.typeQualifiedName(type)}({argTypes})");
                    }
                }
                else
                {
                    targetCtor = ctors[0];
                }

                return(targetCtor.GetActivator());
            });

            return(activator(constructorArgs?.ToArray() ?? TypeConstants.EmptyObjectArray));
        }