public void InitType(Type t)
{
logger.Debug($"Initializing type: {t.AssemblyQualifiedName}");
if (t.IsSimpleType())
{
return;
}
if (typeof(XContainer).IsAssignableFrom(t))
{
typesBeingInitialized.Add(t);
return;
}
if (typeof(IEnumerable).IsAssignableFrom(t))
{
if (t.IsArray)
{
typesToCreateForArrays[t] = typeof(List<>).MakeGenericType(t.GetElementType());
}
foreach (var g in t.GetGenericArguments())
{
InitType(g);
}
//Handle dictionaries - initialize relevant KeyValuePair<T,K> types.
foreach (var interfaceType in t.GetInterfaces())
{
var arr = interfaceType.GetGenericArguments();
if (arr.Length != 1)
{
continue;
}
if (typeof(IEnumerable<>).MakeGenericType(arr[0]).IsAssignableFrom(t))
{
InitType(arr[0]);
}
}
if (t.IsGenericType && t.IsInterface) //handle IEnumerable<Something>
{
var g = t.GetGenericArguments();
var e = typeof(IEnumerable<>).MakeGenericType(g);
if (e.IsAssignableFrom(t))
{
typesToCreateForEnumerables[t] = typeof(List<>).MakeGenericType(g);
}
}
if (t.IsGenericType && t.GetGenericArguments().Length == 1)
{
var setType = typeof(ISet<>).MakeGenericType(t.GetGenericArguments());
if (setType.IsAssignableFrom(t)) //handle ISet<Something>
{
var g = t.GetGenericArguments();
var e = typeof(IEnumerable<>).MakeGenericType(g);
if (e.IsAssignableFrom(t))
{
typesToCreateForEnumerables[t] = typeof(List<>).MakeGenericType(g);
}
}
}
return;
}
var isKeyValuePair = false;
var args = t.GetGenericArguments();
if (args.Length == 2)
{
isKeyValuePair = typeof(KeyValuePair<,>).MakeGenericType(args[0], args[1]) == t;
}
if (args.Length == 1 && args[0].IsValueType)
{
if (args[0].GetGenericArguments().Any() || typeof(Nullable<>).MakeGenericType(args[0]) == t)
{
InitType(args[0]);
if (!args[0].GetGenericArguments().Any())
{
return;
}
}
}
//already in the process of initializing this type (prevents infinite recursion).
if (typesBeingInitialized.Contains(t))
{
return;
}
typesBeingInitialized.Add(t);
var props = GetAllPropertiesForType(t, isKeyValuePair);
typeToProperties[t] = props;
var fields = GetAllFieldsForType(t);
typeToFields[t] = fields;
foreach (var p in props)
{
InitType(p.PropertyType);
}
foreach (var f in fields)
{
InitType(f.FieldType);
}
}