예제 #1
0
        public static void Reset()
        {
            GlobalInstances.Clear();
            GlobalMembers.Clear();
            GlobalNames.Clear();
            GlobalFactories.Clear();

            Register <byte>(1);
            Register <sbyte>(1);
            Register <short>(1);
            Register <ushort>(1);
            Register <int>(1);
            Register <uint>(1);
            Register <long>(1);
            Register <ulong>(1);
            Register <float>(1.0f);
            Register <double>(1.0);
            Register("Foo");
            Register(Guid.Empty);
            Register(new DateTime(2020, 1, 1));
        }
예제 #2
0
        private static object CreateObject(Type t, IDictionary <Type, object> instances)
        {
            if (instances.TryGetValue(t, out var existing) ||
                GlobalInstances.TryGetValue(t, out existing))
            {
                return(existing);
            }

            if (t.IsInterface)
            {
                if (t.IsGenericType && (t.GetGenericTypeDefinition() == typeof(IList <>) || t.GetGenericTypeDefinition() == typeof(IEnumerable <>)))
                {
                    var result = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(t.GenericTypeArguments), 1);
                    instances[t] = result;
                    FillList(result, t, instances);
                    return(result);
                }
                Debug.Assert(false, $"Can't create instance of interface {t}");
            }

            if (IsListType(t))
            {
                var result = (IList)Activator.CreateInstance(t, 1);
                instances[t] = result;
                FillList(result, t, instances);
                return(result);
            }

            if (t.IsClass || (t.IsValueType && !t.IsEnum))
            {
                var ctors = t.GetConstructors().OrderBy(a => a.GetParameters().Length).ToList();

                object result = null;
                if (ctors.Any())
                {
                    var parameters = ctors[0].GetParameters().Select(a => CreateObject(a.ParameterType, instances)).ToArray();
                    result = Activator.CreateInstance(t, parameters);
                }
                else if (GlobalFactories.TryGetValue(t, out var factory))
                {
                    result = factory();
                }
                else
                {
                    result = Activator.CreateInstance(t);
                    Debug.Assert(result != null, $"Unable to create instance of {t}");
                }

                instances[t] = result;
                foreach (var property in t.GetProperties())
                {
                    if (GlobalMembers.TryGetValue(Tuple.Create(property.DeclaringType, property.PropertyType, property.Name), out var value))
                    {
                        property.SetValue(result, value);
                    }
                    else if (property.SetMethod != null)
                    {
                        property.SetValue(result,
                                          GlobalNames.TryGetValue((property.Name, property.PropertyType), out value)
                                ? value
                                : CreateObject(property.PropertyType, instances));
                    }
                    else if (IsListType(property.PropertyType))
                    {
                        var lst = (IList)property.GetValue(result);
                        FillList(lst, property.PropertyType, instances);
                    }
                }

                return(result);
            }

            return(instances[t] = Activator.CreateInstance(t));
        }