bool TryAddParameters(Type classType, Type interfaceType, Type[] parameters, Type[] openClassArguments)
{
if (interfaceType.ContainsGenericParameters == false)
{
return classType.Is(interfaceType);
}
// for now we only allow that if it's a generic argument of the sourceType
var index = Array.IndexOf(openClassArguments, interfaceType);
if (index == -1)
{
if (interfaceType.IsGenericType)
{
if (classType.IsGenericType == false)
{
return false;
}
var openInterfaceType = interfaceType.GetGenericTypeDefinition();
var openClassType = classType.GetGenericTypeDefinition();
// we don't support assignable types for now
if (openInterfaceType != openClassType)
{
return false;
}
var interfaceGenericArguments = interfaceType.GetGenericArguments();
var classGenericArguments = classType.GetGenericArguments();
for (var i = 0; i < interfaceGenericArguments.Length; i++)
{
if (interfaceGenericArguments[i].ContainsGenericParameters)
{
// for now we only allow that if it's a generic argument of the sourceType
index = Array.IndexOf(openClassArguments, interfaceGenericArguments[i]);
if (index == -1)
{
return false;
}
parameters[index] = EnsureMeetsGenericConstraints(classGenericArguments[i], interfaceGenericArguments[i]);
}
}
}
if (interfaceType.IsArray)
{
var classArrayItemType = classType.GetArrayItemType();
if (classArrayItemType != null)
{
var interfaceArrayItemType = interfaceType.GetElementType();
// for now we only allow that if it's a generic argument of the sourceType
index = Array.IndexOf(openClassArguments, interfaceArrayItemType);
if (index == -1)
{
return false;
}
parameters[index] = EnsureMeetsGenericConstraints(classArrayItemType, interfaceArrayItemType);
}
}
}
else
{
parameters[index] = EnsureMeetsGenericConstraints(classType, interfaceType);
}
return true;
}