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)); }
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)); }