diff --git a/src/NeinLinq/InjectLambdaSignature.cs b/src/NeinLinq/InjectLambdaSignature.cs index a02daa8..5bfd65d 100644 --- a/src/NeinLinq/InjectLambdaSignature.cs +++ b/src/NeinLinq/InjectLambdaSignature.cs @@ -7,6 +7,8 @@ namespace NeinLinq { sealed class InjectLambdaSignature { + const BindingFlags everything = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance; + readonly Type[] genericArguments; readonly Type[] parameterTypes; @@ -35,7 +37,7 @@ public MethodInfo FindFactory(Type target, string method) { // assume method without any parameters var factory = FindMatch(target, method, genericArguments, Type.EmptyTypes) - ?? target.GetProperty(method)?.GetMethod; + ?? target.GetProperty(method, everything)?.GetMethod; if (factory == null) throw FailFactory(target, method, "no matching parameterless member found"); @@ -74,7 +76,7 @@ public MethodInfo FindMatch(Type target, string method) static MethodInfo FindMatch(Type target, string method, Type[] genericArguments, Type[] parameterTypes) { - foreach (var candidate in target.GetMethods()) + foreach (var candidate in target.GetMethods(everything)) { // non-matching name? if (candidate.Name != method) diff --git a/test/NeinLinq.Fakes/InjectableQuery/ConcreteFunctions.cs b/test/NeinLinq.Fakes/InjectableQuery/ConcreteFunctions.cs index 1657004..a4ab62d 100644 --- a/test/NeinLinq.Fakes/InjectableQuery/ConcreteFunctions.cs +++ b/test/NeinLinq.Fakes/InjectableQuery/ConcreteFunctions.cs @@ -70,5 +70,10 @@ public Expression> VelocityWithInvalidGenericArguments() { return v => Math.Round(v.Distance / v.Time, digits); } + + Expression> VelocityWithNonPublicSibling() + { + return v => Math.Round(v.Distance / v.Time, digits); + } } } diff --git a/test/NeinLinq.Fakes/InjectableQuery/Dummy.cs b/test/NeinLinq.Fakes/InjectableQuery/Dummy.cs index a8dd01e..9db791c 100644 --- a/test/NeinLinq.Fakes/InjectableQuery/Dummy.cs +++ b/test/NeinLinq.Fakes/InjectableQuery/Dummy.cs @@ -69,5 +69,9 @@ public double VelocityExternalWithGetter public double VelocityWithInvalidSiblingSignature { get; } public static Expression> VelocityWithInvalidSiblingSignatureExpr => (d, t) => d / t; + + public double VelocityWithNonPublicSibling { get; } + + static Expression> VelocityWithNonPublicSiblingExpr => v => v.Distance / v.Time; } } diff --git a/test/NeinLinq.Fakes/InjectableQuery/Functions.cs b/test/NeinLinq.Fakes/InjectableQuery/Functions.cs index c85633b..5e1b3c1 100644 --- a/test/NeinLinq.Fakes/InjectableQuery/Functions.cs +++ b/test/NeinLinq.Fakes/InjectableQuery/Functions.cs @@ -117,5 +117,15 @@ public static Expression> VelocityWithInvalidGenericArgument { return v => v.Distance / v.Time; } + + public static double VelocityWithNonPublicSibling(this Dummy value) + { + throw new NotSupportedException(); + } + + static Expression> VelocityWithNonPublicSibling() + { + return v => v.Distance / v.Time; + } } } diff --git a/test/NeinLinq.Fakes/InjectableQuery/FunctionsBase.cs b/test/NeinLinq.Fakes/InjectableQuery/FunctionsBase.cs index a3ad4b7..1810c0c 100644 --- a/test/NeinLinq.Fakes/InjectableQuery/FunctionsBase.cs +++ b/test/NeinLinq.Fakes/InjectableQuery/FunctionsBase.cs @@ -78,5 +78,10 @@ public double VelocityWithInvalidGenericArguments(TDummy value) { throw new NotSupportedException(); } + + public double VelocityWithNonPublicSibling(Dummy value) + { + throw new NotSupportedException(); + } } } diff --git a/test/NeinLinq.Fakes/InjectableQuery/IFunctions.cs b/test/NeinLinq.Fakes/InjectableQuery/IFunctions.cs index eb103c8..4474d7d 100644 --- a/test/NeinLinq.Fakes/InjectableQuery/IFunctions.cs +++ b/test/NeinLinq.Fakes/InjectableQuery/IFunctions.cs @@ -25,5 +25,7 @@ double VelocityWithGenericArguments(TDummy value) double VelocityWithInvalidGenericArguments(TDummy value) where TDummy : IDummy; + + double VelocityWithNonPublicSibling(Dummy value); } } diff --git a/test/NeinLinq.Tests/InjectableQuery/QueryBaseTest.cs b/test/NeinLinq.Tests/InjectableQuery/QueryBaseTest.cs index 5eb5157..735cec6 100644 --- a/test/NeinLinq.Tests/InjectableQuery/QueryBaseTest.cs +++ b/test/NeinLinq.Tests/InjectableQuery/QueryBaseTest.cs @@ -121,5 +121,16 @@ public void ShouldFailWithInvalidGenericArguments() Assert.Equal("Unable to retrieve lambda expression from NeinLinq.Fakes.InjectableQuery.ConcreteFunctions.VelocityWithInvalidGenericArguments: no matching parameterless member found.", error.Message); } + + [Fact] + public void ShouldSucceedWithNonPublicSibling() + { + var query = from d in data.ToInjectable(typeof(FunctionsBase)) + select functions.VelocityWithNonPublicSibling(d); + + var result = query.ToList(); + + Assert.Equal(new[] { 200.0, .0, .1 }, result); + } } } diff --git a/test/NeinLinq.Tests/InjectableQuery/QueryConcreteTest.cs b/test/NeinLinq.Tests/InjectableQuery/QueryConcreteTest.cs index fe71242..bef120f 100644 --- a/test/NeinLinq.Tests/InjectableQuery/QueryConcreteTest.cs +++ b/test/NeinLinq.Tests/InjectableQuery/QueryConcreteTest.cs @@ -121,5 +121,16 @@ public void ShouldFailWithInvalidGenericArguments() Assert.Equal("Unable to retrieve lambda expression from NeinLinq.Fakes.InjectableQuery.ConcreteFunctions.VelocityWithInvalidGenericArguments: no matching parameterless member found.", error.Message); } + + [Fact] + public void ShouldSucceedWithNonPublicSibling() + { + var query = from d in data.ToInjectable(typeof(ConcreteFunctions)) + select functions.VelocityWithNonPublicSibling(d); + + var result = query.ToList(); + + Assert.Equal(new[] { 200.0, .0, .1 }, result); + } } } diff --git a/test/NeinLinq.Tests/InjectableQuery/QueryInterfaceTest.cs b/test/NeinLinq.Tests/InjectableQuery/QueryInterfaceTest.cs index 007f0fa..c0a0bb2 100644 --- a/test/NeinLinq.Tests/InjectableQuery/QueryInterfaceTest.cs +++ b/test/NeinLinq.Tests/InjectableQuery/QueryInterfaceTest.cs @@ -121,5 +121,16 @@ public void ShouldFailWithInvalidGenericArguments() Assert.Equal("Unable to retrieve lambda expression from NeinLinq.Fakes.InjectableQuery.ConcreteFunctions.VelocityWithInvalidGenericArguments: no matching parameterless member found.", error.Message); } + + [Fact] + public void ShouldSucceedWithNonPublicSibling() + { + var query = from d in data.ToInjectable(typeof(IFunctions)) + select functions.VelocityWithNonPublicSibling(d); + + var result = query.ToList(); + + Assert.Equal(new[] { 200.0, .0, .1 }, result); + } } } diff --git a/test/NeinLinq.Tests/InjectableQuery/QueryPropertyTest.cs b/test/NeinLinq.Tests/InjectableQuery/QueryPropertyTest.cs index 8bd1f43..141d41e 100644 --- a/test/NeinLinq.Tests/InjectableQuery/QueryPropertyTest.cs +++ b/test/NeinLinq.Tests/InjectableQuery/QueryPropertyTest.cs @@ -174,5 +174,16 @@ public void ShouldFailWithInvalidSiblingSignature() Assert.Equal("Unable to retrieve lambda expression from NeinLinq.Fakes.InjectableQuery.Dummy.VelocityWithInvalidSiblingSignatureExpr: returns non-matching expression.", error.Message); } + + [Fact] + public void ShouldSucceedWithNonPublicSibling() + { + var query = from d in data.ToInjectable(typeof(Dummy)) + select d.VelocityWithNonPublicSibling; + + var result = query.ToList(); + + Assert.Equal(new[] { 200.0, .0, .125 }, result); + } } } diff --git a/test/NeinLinq.Tests/InjectableQuery/QueryStaticTest.cs b/test/NeinLinq.Tests/InjectableQuery/QueryStaticTest.cs index 009dd08..3ff2c93 100644 --- a/test/NeinLinq.Tests/InjectableQuery/QueryStaticTest.cs +++ b/test/NeinLinq.Tests/InjectableQuery/QueryStaticTest.cs @@ -141,5 +141,16 @@ public void ShouldFailWithInvalidGenericArguments() Assert.Equal("Unable to retrieve lambda expression from NeinLinq.Fakes.InjectableQuery.Functions.VelocityWithInvalidGenericArguments: no matching parameterless member found.", error.Message); } + + [Fact] + public void ShouldSucceedWithNonPublicSibling() + { + var query = from d in data.ToInjectable(typeof(Functions)) + select d.VelocityWithNonPublicSibling(); + + var result = query.ToList(); + + Assert.Equal(new[] { 200.0, .0, .125 }, result); + } } }