private static IDictionary<Type, Type> MatchTypesByGenerics(Type[] types, TypeInfo genericTypeDefinition, TypeInfo baseTypeDefinition) { return types .Where(t => t.GetTypeInfo().IsClass && baseTypeDefinition.IsAssignableFrom(t.GetTypeInfo())).ToArray() .ToDictionary(x => genericTypeDefinition.MakeGenericType(x), x => { var genericTypeBase = genericTypeDefinition.MakeGenericType(x); var result = types.Where(t => genericTypeBase.GetTypeInfo().IsAssignableFrom(t.GetTypeInfo())).ToArray(); if (result.Length > 1) throw new AmbiguousMatchException($"Ambiguous match found for {x.FullName}: {String.Join(", ", result.Select(t => t.FullName))}"); return result.FirstOrDefault(); }); }