Skip to content

Commit

Permalink
Allow instance to static injection
Browse files Browse the repository at this point in the history
  • Loading branch information
akarboush committed Aug 19, 2024
1 parent 0c5d7c1 commit d349c71
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 deletions.
7 changes: 5 additions & 2 deletions src/NeinLinq/InjectLambdaMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,11 @@ public static InjectLambdaMetadata Create(PropertyInfo property)
// retrieve validated factory method
var factoryMethod = signature.FindFactory(targetType, metadata.Method ?? method.Name, value.Type);

var callExpression = factoryMethod.IsStatic
? Expression.Call(factoryMethod)
: Expression.Call(Expression.Convert(value, targetType), factoryMethod);

// finally call lambda factory *uff*
return Expression.Lambda<Func<LambdaExpression>>(
Expression.Convert(Expression.Call(Expression.Convert(value, targetType), factoryMethod), typeof(LambdaExpression))).Compile()();
return Expression.Lambda<Func<LambdaExpression>>(Expression.Convert(callExpression, typeof(LambdaExpression))).Compile()();
};
}
4 changes: 2 additions & 2 deletions src/NeinLinq/InjectLambdaSignature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ public MethodInfo FindFactory(Type target, string method, Type? injectedType = n
factory = factory.MakeGenericMethod(genericArguments);

// mixed static and non-static methods?
if (factory.IsStatic != isStatic)
throw FailFactory(target, factory.Name, $"{(isStatic ? "static" : "non-static")} implementation expected");
if (!factory.IsStatic && isStatic)
throw FailFactory(target, factory.Name, "static implementation expected");

// method returns lambda expression?
if (!IsLambdaExpression(factory.ReturnType))
Expand Down
34 changes: 34 additions & 0 deletions test/NeinLinq.Tests/InjectLambdaQueryTest.Inheritance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,30 @@ public void Query_WithCachedExpression_Injects()
Assert.Equal([200.0, .0, .12], result);
}

[Fact]
public void Query_WithHiddenStaticSiblingViaBase_Injects()
{
FunctionsBase functions = new Functions(2);

var query = CreateQuery().ToInjectable().Select(m => functions.VelocityWithHiddenStaticSibling(m));

var result = query.ToList();

Assert.Equal([200, 0, 0.125], result);
}

[Fact]
public void Query_WithHiddenStaticSiblingViaDerived_Injects()
{
var functions = new Functions(2);

var query = CreateQuery().ToInjectable().Select(m => functions.VelocityWithHiddenStaticSibling(m));

var result = query.ToList();

Assert.Equal([200, 0, 0.125], result);
}

private static IQueryable<Model> CreateQuery()
{
var data = new[]
Expand Down Expand Up @@ -380,6 +404,13 @@ public virtual Expression<Func<Model, double>> VelocityWithVirtualSibling()
[InjectLambda]
public double VelocityWithCachedExpression(Model value)
=> throw new NotSupportedException($"Unable to process {value.Name}.");

[InjectLambda]
public double VelocityWithHiddenStaticSibling(Model value)
=> throw new NotSupportedException($"Unable to process {value.Name}.");

public static Expression<Func<Model, double>> VelocityWithHiddenStaticSibling()
=> throw new InvalidOperationException("Implementing sibling is missing.");
}

private class Functions : FunctionsBase
Expand Down Expand Up @@ -446,5 +477,8 @@ public override Expression<Func<Model, double>> VelocityWithVirtualSibling()

private CachedExpression<Func<Model, double>> VelocityWithCachedExpressionExpr { get; }
= CachedExpression.From<Func<Model, double>>(v => Math.Round(v.Distance / v.Time, 2));

public new static Expression<Func<Model, double>> VelocityWithHiddenStaticSibling()
=> v => v.Distance / v.Time;
}
}
6 changes: 3 additions & 3 deletions test/NeinLinq.Tests/InjectLambdaQueryTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ public void Query_StaticToInstance_Throws()
}

[Fact]
public void Query_InstanceToStatic_Throws()
public void Query_InstanceToStatic_DontThrow()
{
var functions = new MixedFunctions(1);

var query = CreateQuery().ToInjectable(typeof(MixedFunctions)).Select(m => functions.VelocityInstanceToStatic(m));

var error = Assert.Throws<InvalidOperationException>(() => query.ToList());
var result = query.ToList();

Assert.Equal("Unable to retrieve lambda expression from NeinLinq.Tests.InjectLambdaQueryTest+MixedFunctions.VelocityInstanceToStatic: non-static implementation expected.", error.Message);
Assert.Equal([200.0, .0, .125], result);
}

private static IQueryable<Model> CreateQuery()
Expand Down

0 comments on commit d349c71

Please sign in to comment.