Finishing genre link equality

This commit is contained in:
Zoe Roux 2021-01-29 23:02:07 +01:00
parent 1902740d2f
commit bef687bbb1
3 changed files with 36 additions and 12 deletions

View File

@ -40,7 +40,7 @@ namespace Kyoo.Models
} }
} }
public class LinkComparer<T, T1, T2> : IEqualityComparer<T>> public class LinkComparer<T, T1, T2> : IEqualityComparer<T>
where T : IResourceLink<T1, T2> where T : IResourceLink<T1, T2>
where T1 : IResource where T1 : IResource
where T2 : IResource where T2 : IResource

View File

@ -206,24 +206,50 @@ namespace Kyoo
: type.GetInheritanceTree(); : type.GetInheritanceTree();
return types.Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType); return types.Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType);
} }
public static Type GetGenericDefinition([NotNull] Type type, [NotNull] Type genericType)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
if (genericType == null)
throw new ArgumentNullException(nameof(genericType));
if (!genericType.IsGenericType)
throw new ArgumentException($"{nameof(genericType)} is not a generic type.");
IEnumerable<Type> types = genericType.IsInterface
? type.GetInterfaces()
: type.GetInheritanceTree();
return types.FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType);
}
public static T RunGenericMethod<T>( public static T RunGenericMethod<T>(
[NotNull] Type owner, [NotNull] Type owner,
[NotNull] string methodName, [NotNull] string methodName,
[NotNull] Type type, [NotNull] Type type,
params object[] args) params object[] args)
{
return RunGenericMethod<T>(owner, methodName, new[] {type}, args);
}
public static T RunGenericMethod<T>(
[NotNull] Type owner,
[NotNull] string methodName,
[NotNull] Type[] types,
params object[] args)
{ {
if (owner == null) if (owner == null)
throw new ArgumentNullException(nameof(owner)); throw new ArgumentNullException(nameof(owner));
if (methodName == null) if (methodName == null)
throw new ArgumentNullException(nameof(methodName)); throw new ArgumentNullException(nameof(methodName));
if (type == null) if (types == null)
throw new ArgumentNullException(nameof(type)); throw new ArgumentNullException(nameof(types));
if (types.Length < 1)
throw new ArgumentException($"The {nameof(types)} array is empty. At least one type is needed.");
MethodInfo method = owner.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) MethodInfo method = owner.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
.SingleOrDefault(x => x.Name == methodName && x.GetParameters().Length == args.Length); .SingleOrDefault(x => x.Name == methodName && x.GetParameters().Length == args.Length);
if (method == null) if (method == null)
throw new NullReferenceException($"A method named {methodName} with {args.Length} arguments could not be found on {owner.FullName}"); throw new NullReferenceException($"A method named {methodName} with {args.Length} arguments could not be found on {owner.FullName}");
return (T)method.MakeGenericMethod(type).Invoke(null, args?.ToArray()); return (T)method.MakeGenericMethod(types).Invoke(null, args?.ToArray());
} }
public static T RunGenericMethod<T>( public static T RunGenericMethod<T>(
@ -342,7 +368,7 @@ namespace Kyoo
return (T)((dynamic)x).Result; return (T)((dynamic)x).Result;
}, TaskContinuationOptions.ExecuteSynchronously); }, TaskContinuationOptions.ExecuteSynchronously);
} }
public static bool ResourceEquals([CanBeNull] object first, [CanBeNull] object second) public static bool ResourceEquals([CanBeNull] object first, [CanBeNull] object second)
{ {
if (ReferenceEquals(first, second)) if (ReferenceEquals(first, second))
@ -356,11 +382,11 @@ namespace Kyoo
Type type = GetEnumerableType(eno); Type type = GetEnumerableType(eno);
if (typeof(IResource).IsAssignableFrom(type)) if (typeof(IResource).IsAssignableFrom(type))
return ResourceEquals(eno.Cast<IResource>(), ens.Cast<IResource>()); return ResourceEquals(eno.Cast<IResource>(), ens.Cast<IResource>());
// TODO find a way to run the equality checker with the right check. Type genericDefinition = GetGenericDefinition(type, typeof(IResourceLink<,>));
// TODO maybe create a GetTypeOfGenericType if (genericDefinition == null)
// if (IsOfGenericType(type, typeof(IResourceLink<,>))) return RunGenericMethod<bool>(typeof(Enumerable), "SequenceEqual", type, first, second);
// return ResourceEquals(eno.Cast<IResourceLink<,>>()) Type[] types = genericDefinition.GetGenericArguments().Prepend(type).ToArray();
return RunGenericMethod<bool>(typeof(Enumerable), "SequenceEqual", type, first, second); return RunGenericMethod<bool>(typeof(Utility), "LinkEquals", types, eno, ens);
} }
public static bool ResourceEquals<T>([CanBeNull] T first, [CanBeNull] T second) public static bool ResourceEquals<T>([CanBeNull] T first, [CanBeNull] T second)

View File

@ -4,9 +4,7 @@ using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Kyoo.Models; using Kyoo.Models;
using Kyoo.Models.Exceptions;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace Kyoo.Controllers namespace Kyoo.Controllers
{ {