From bef687bbb1365068d27a6c6a7cf06b609e51df88 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Fri, 29 Jan 2021 23:02:07 +0100 Subject: [PATCH] Finishing genre link equality --- Kyoo.Common/Models/Resources/IResource.cs | 2 +- Kyoo.Common/Utility.cs | 44 +++++++++++++++---- .../Repositories/GenreRepository.cs | 2 - 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/Kyoo.Common/Models/Resources/IResource.cs b/Kyoo.Common/Models/Resources/IResource.cs index dfdfcb63..f20179a7 100644 --- a/Kyoo.Common/Models/Resources/IResource.cs +++ b/Kyoo.Common/Models/Resources/IResource.cs @@ -40,7 +40,7 @@ namespace Kyoo.Models } } - public class LinkComparer : IEqualityComparer> + public class LinkComparer : IEqualityComparer where T : IResourceLink where T1 : IResource where T2 : IResource diff --git a/Kyoo.Common/Utility.cs b/Kyoo.Common/Utility.cs index 0c4f8c0d..8000f1be 100644 --- a/Kyoo.Common/Utility.cs +++ b/Kyoo.Common/Utility.cs @@ -206,24 +206,50 @@ namespace Kyoo : type.GetInheritanceTree(); 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 types = genericType.IsInterface + ? type.GetInterfaces() + : type.GetInheritanceTree(); + return types.FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType); + } public static T RunGenericMethod( [NotNull] Type owner, [NotNull] string methodName, [NotNull] Type type, params object[] args) + { + return RunGenericMethod(owner, methodName, new[] {type}, args); + } + + public static T RunGenericMethod( + [NotNull] Type owner, + [NotNull] string methodName, + [NotNull] Type[] types, + params object[] args) { if (owner == null) throw new ArgumentNullException(nameof(owner)); if (methodName == null) throw new ArgumentNullException(nameof(methodName)); - if (type == null) - throw new ArgumentNullException(nameof(type)); + if (types == null) + 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) .SingleOrDefault(x => x.Name == methodName && x.GetParameters().Length == args.Length); if (method == null) 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( @@ -342,7 +368,7 @@ namespace Kyoo return (T)((dynamic)x).Result; }, TaskContinuationOptions.ExecuteSynchronously); } - + public static bool ResourceEquals([CanBeNull] object first, [CanBeNull] object second) { if (ReferenceEquals(first, second)) @@ -356,11 +382,11 @@ namespace Kyoo Type type = GetEnumerableType(eno); if (typeof(IResource).IsAssignableFrom(type)) return ResourceEquals(eno.Cast(), ens.Cast()); - // TODO find a way to run the equality checker with the right check. - // TODO maybe create a GetTypeOfGenericType - // if (IsOfGenericType(type, typeof(IResourceLink<,>))) - // return ResourceEquals(eno.Cast>()) - return RunGenericMethod(typeof(Enumerable), "SequenceEqual", type, first, second); + Type genericDefinition = GetGenericDefinition(type, typeof(IResourceLink<,>)); + if (genericDefinition == null) + return RunGenericMethod(typeof(Enumerable), "SequenceEqual", type, first, second); + Type[] types = genericDefinition.GetGenericArguments().Prepend(type).ToArray(); + return RunGenericMethod(typeof(Utility), "LinkEquals", types, eno, ens); } public static bool ResourceEquals([CanBeNull] T first, [CanBeNull] T second) diff --git a/Kyoo/Controllers/Repositories/GenreRepository.cs b/Kyoo/Controllers/Repositories/GenreRepository.cs index 549c2dc5..3a2261c6 100644 --- a/Kyoo/Controllers/Repositories/GenreRepository.cs +++ b/Kyoo/Controllers/Repositories/GenreRepository.cs @@ -4,9 +4,7 @@ using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; using Kyoo.Models; -using Kyoo.Models.Exceptions; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; namespace Kyoo.Controllers {