private static bool GetGenericTypeArgumentsForInterface(Type type, Type genericType, out DataConverterResult result) { result = new DataConverterResult(); var typeInfo = type.GetTypeInfo(); var genericTypeInfo = genericType.GetTypeInfo(); // Check the type itself if (typeInfo.IsGenericType && type.GetGenericTypeDefinition() == genericType) { result.InterfaceType = type; result.Type = type; return(true); } // If interface, let's check its implemented interfaces as well if (genericTypeInfo.IsInterface) { foreach (var @interface in typeInfo.ImplementedInterfaces) { var interfaceTypeInfo = @interface.GetTypeInfo(); if (interfaceTypeInfo.IsGenericType && interfaceTypeInfo.GetGenericTypeDefinition() == genericType) { result.InterfaceType = interfaceTypeInfo.AsType(); result.Type = type; return(true); } } } return(false); }
private static bool GetDataConverter(Type dataType, Type objectType, Type genericType, ConversionType conversionType, out DataConverterResult dataResult, out DataConverterResult objectResult) { bool objectResultFound = GetGenericTypeArgumentsForInterface(objectType, genericType, out objectResult); bool dataResultFound = GetGenericTypeArgumentsForInterface(dataType, genericType, out dataResult); switch (conversionType) { case ConversionType.ObjectToData: if (objectResultFound && !dataResultFound) { dataResultFound = true; var genericTypeArguments = objectResult.InterfaceType.GenericTypeArguments.Select(x => { var dataConverter = GetDataConverter(typeof(object), x, conversionType); return(dataConverter != null ? dataConverter.DataType : x); }); dataResult.Type = dataResult.InterfaceType = genericType.MakeGenericType(genericTypeArguments.ToArray()); } break; case ConversionType.DataToObject: if (dataResultFound && !objectResultFound) { objectResultFound = true; var genericTypeArguments = dataResult.InterfaceType.GenericTypeArguments.Select(x => { var dataConverter = GetDataConverter(x, typeof(object), conversionType); return(dataConverter != null ? dataConverter.ObjectType : x); }); objectResult.Type = objectResult.InterfaceType = genericType.MakeGenericType(genericTypeArguments.ToArray()); } break; default: throw new ArgumentOutOfRangeException("conversionType"); } return(objectResultFound && dataResultFound); }