From b92df9833d439f06cdf2cfe7f6ab9732af5f98eb Mon Sep 17 00:00:00 2001 From: Biarity Date: Wed, 4 Jul 2018 13:06:37 +1000 Subject: [PATCH] Fixes #33 --- Sieve/Extensions/MethodInfoExtended.cs | 35 ++++++++++---------------- Sieve/Services/SieveProcessor.cs | 23 +++++++++-------- SieveUnitTests/General.cs | 13 ++++++++++ 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/Sieve/Extensions/MethodInfoExtended.cs b/Sieve/Extensions/MethodInfoExtended.cs index 009fdbc..d7aff02 100644 --- a/Sieve/Extensions/MethodInfoExtended.cs +++ b/Sieve/Extensions/MethodInfoExtended.cs @@ -18,7 +18,7 @@ namespace Sieve.Extensions /// public static MethodInfo GetMethodExt(this Type thisType, string name, - params Type[] parameterTypes) + Type firstType) { return GetMethodExt(thisType, name, @@ -27,7 +27,7 @@ namespace Sieve.Extensions | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy, - parameterTypes); + firstType); } /// @@ -39,12 +39,12 @@ namespace Sieve.Extensions public static MethodInfo GetMethodExt(this Type thisType, string name, BindingFlags bindingFlags, - params Type[] parameterTypes) + Type firstType) { MethodInfo matchingMethod = null; // Check all methods with the specified name, including in base classes - GetMethodExt(ref matchingMethod, thisType, name, bindingFlags, parameterTypes); + GetMethodExt(ref matchingMethod, thisType, name, bindingFlags, firstType); // If we're searching an interface, we have to manually search base interfaces if (matchingMethod == null && thisType.IsInterface) @@ -54,7 +54,7 @@ namespace Sieve.Extensions interfaceType, name, bindingFlags, - parameterTypes); + firstType); } return matchingMethod; @@ -64,7 +64,7 @@ namespace Sieve.Extensions Type type, string name, BindingFlags bindingFlags, - params Type[] parameterTypes) + Type firstType) { // Check all methods with the specified name, including in base classes foreach (MethodInfo methodInfo in type.GetMember(name, @@ -74,23 +74,14 @@ namespace Sieve.Extensions // Check that the parameter counts and types match, // with 'loose' matching on generic parameters ParameterInfo[] parameterInfos = methodInfo.GetParameters(); - if (parameterInfos.Length == parameterTypes.Length) + + if (parameterInfos[0].ParameterType.IsSimilarType(firstType)) { - int i = 0; - for (; i < parameterInfos.Length; ++i) - { - if (!parameterInfos[i].ParameterType - .IsSimilarType(parameterTypes[i])) - break; - } - if (i == parameterInfos.Length) - { - if (matchingMethod == null) - matchingMethod = methodInfo; - else - throw new AmbiguousMatchException( - "More than one matching method found!"); - } + if (matchingMethod == null) + matchingMethod = methodInfo; + else + throw new AmbiguousMatchException( + "More than one matching method found!"); } } } diff --git a/Sieve/Services/SieveProcessor.cs b/Sieve/Services/SieveProcessor.cs index 4a8bcc4..8c2eb19 100644 --- a/Sieve/Services/SieveProcessor.cs +++ b/Sieve/Services/SieveProcessor.cs @@ -180,7 +180,7 @@ namespace Sieve.Services if (property != null) { var converter = TypeDescriptor.GetConverter(property.PropertyType); - + dynamic constantVal = converter.CanConvertFrom(typeof(string)) ? converter.ConvertFrom(filterTerm.Value) : Convert.ChangeType(filterTerm.Value, property.PropertyType); @@ -211,13 +211,13 @@ namespace Sieve.Services } else { - var parameters = new object[] { + result = ApplyCustomMethod(result, filterTermName, _customFilterMethods, + new object[] { result, filterTerm.Operator, filterTerm.Value - }; - result = ApplyCustomMethod(result, filterTermName, _customFilterMethods, parameters, dataForCustomMethods); - + }, dataForCustomMethods); + } } if (outerExpression == null) @@ -347,20 +347,23 @@ namespace Sieve.Services bool canSortRequired, bool canFilterRequired, string name, - bool isCaseSensitive) => Array.Find(typeof(TEntity).GetProperties(), p => - { - return p.GetCustomAttribute(typeof(SieveAttribute)) is SieveAttribute sieveAttribute + bool isCaseSensitive) + { + return Array.Find(typeof(TEntity).GetProperties(), p => + { + return p.GetCustomAttribute(typeof(SieveAttribute)) is SieveAttribute sieveAttribute && (canSortRequired ? sieveAttribute.CanSort : true) && (canFilterRequired ? sieveAttribute.CanFilter : true) && ((sieveAttribute.Name ?? p.Name).Equals(name, isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase)); - }); + }); + } private IQueryable ApplyCustomMethod(IQueryable result, string name, object parent, object[] parameters, object[] optionalParameters = null) { var customMethod = parent?.GetType() .GetMethodExt(name, _options.Value.CaseSensitive ? BindingFlags.Default : BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance, - new Type[] { typeof(IQueryable), typeof(string), typeof(string) }); + typeof(IQueryable)); if (customMethod != null) { diff --git a/SieveUnitTests/General.cs b/SieveUnitTests/General.cs index efa9b00..f0eacff 100644 --- a/SieveUnitTests/General.cs +++ b/SieveUnitTests/General.cs @@ -224,6 +224,19 @@ namespace SieveUnitTests Assert.AreEqual(2, commentResult.Count()); } + [TestMethod] + public void CustomSortsWork() + { + var model = new SieveModel() + { + Sorts = "Popularity", + }; + + var result = _processor.Apply(model, _posts); + + Assert.IsFalse(result.First().Id == 0); + } + [TestMethod] public void MethodNotFoundExceptionWork() {