static Func <Expression, LambdaExpression> FixedLambdaFactory(InjectLambdaAttribute metadata, Type target, string method, Type[] args, Type result, bool instance) { // apply configuration, if any if (metadata != null) { if (metadata.Target != null) { target = metadata.Target; } if (!string.IsNullOrEmpty(metadata.Method)) { method = metadata.Method; } } // retrieve validated factory method once var factory = FactoryMethod(target, method, args, result, instance); if (factory.IsStatic) { // compile factory call for performance reasons :-) return(Expression.Lambda <Func <Expression, LambdaExpression> >( Expression.Call(factory), Expression.Parameter(typeof(Expression))).Compile()); } // call actual target object, compiles every time during execution... :-| return(value => Expression.Lambda <Func <LambdaExpression> >(Expression.Call(value, factory)).Compile()()); }
public static InjectLambdaMetadata Create(MethodInfo method) { var metadata = InjectLambdaAttribute.GetCustomAttribute(method); var lambdaFactory = new Lazy <Func <Expression, LambdaExpression> >(() => LambdaFactory(method, metadata ?? InjectLambdaAttribute.None)); return(new InjectLambdaMetadata(metadata != null, lambdaFactory)); }
public static InjectLambdaMetadata Create(PropertyInfo property) { var metadata = InjectLambdaAttribute.GetCustomAttribute(property) ?? InjectLambdaAttribute.GetCustomAttribute(property.GetGetMethod(true)); var lambdaFactory = new Lazy <Func <Expression, LambdaExpression> >(() => LambdaFactory(property, metadata ?? InjectLambdaAttribute.None)); return(new InjectLambdaMetadata(metadata != null, lambdaFactory)); }
static Func <Expression, LambdaExpression> LambdaFactory(MethodInfo method, InjectLambdaAttribute metadata) { // retrieve method's signature var signature = new InjectLambdaSignature(method); // special ultra-fast treatment for static methods and sealed classes if (method.IsStatic || method.DeclaringType.IsSealed) { return(FixedLambdaFactory(metadata.Target ?? method.DeclaringType, metadata.Method ?? method.Name, signature)); } // dynamic but not that fast treatment for other stuff return(DynamicLambdaFactory(method.Name, signature)); }
static Func <Expression, LambdaExpression> LambdaFactory(MethodInfo method, InjectLambdaAttribute metadata) { // retrieve method's signature var args = method.GetParameters().Select(p => p.ParameterType).ToArray(); var result = method.ReturnParameter.ParameterType; // special ultra-fast treatment for static methods and sealed classes if (method.IsStatic || method.DeclaringType.GetTypeInfo().IsSealed) { return(FixedLambdaFactory(metadata, method.DeclaringType, method.Name, args, result, !method.IsStatic)); } // dynamic but not that fast treatment for other stuff return(DynamicLambdaFactory(method.Name, args, result)); }
private static Func <Expression, LambdaExpression> DynamicLambdaFactory(string method, InjectLambdaSignature signature) { return(value => { // retrieve actual target object, compiles every time and needs reflection too... :-( var targetObject = Expression.Lambda <Func <object> >(Expression.Convert(value, typeof(object))).Compile()(); // retrieve actual target type at runtime, whatever it may be var target = targetObject.GetType(); // actual method may provide different information var concreteMethod = signature.FindMatch(target, method); // configuration over convention, if any var metadata = InjectLambdaAttribute.GetCustomAttribute(concreteMethod) ?? InjectLambdaAttribute.None; // retrieve validated factory method var factory = signature.FindFactory(target, metadata.Method ?? method); // finally call lambda factory *uff* return (LambdaExpression)factory.Invoke(targetObject, null); }); }
private static Func <Expression, LambdaExpression> LambdaFactory(PropertyInfo property, InjectLambdaAttribute metadata) { // retrieve method's signature var signature = new InjectLambdaSignature(property); // apply "Expr" convention for property "overloading" var method = metadata.Target == null ? property.Name + "Expr" : property.Name; // special treatment for super-heroic property getters return(FixedLambdaFactory(metadata.Target ?? property.DeclaringType, metadata.Method ?? method, signature)); }
static Func <Expression, LambdaExpression> LambdaFactory(PropertyInfo property, InjectLambdaAttribute metadata) { // retrieve method's signature var args = new[] { property.DeclaringType }; var result = property.PropertyType; // special treatment for super-heroic property getters return(FixedLambdaFactory(metadata, property.DeclaringType, property.Name, args, result, false)); }
private static Func <Expression?, LambdaExpression?> LambdaFactory(PropertyInfo property, InjectLambdaAttribute metadata) { if (property.DeclaringType is null) { throw new InvalidOperationException($"Property {property.Name} has no declaring type."); } // retrieve method's signature var signature = new InjectLambdaSignature(property); // apply "Expr" convention for property "overloading" var method = metadata.Target is null ? property.Name + "Expr" : property.Name; // special treatment for super-heroic property getters return(FixedLambdaFactory(metadata.Target ?? property.DeclaringType, metadata.Method ?? method, signature)); }
private static Func <Expression?, LambdaExpression?> LambdaFactory(MethodInfo method, InjectLambdaAttribute metadata) { if (method.DeclaringType is null) { throw new InvalidOperationException($"Method {method.Name} has no declaring type."); } // retrieve method's signature var signature = new InjectLambdaSignature(method); // special ultra-fast treatment for static methods and sealed classes if (method.IsStatic || method.DeclaringType.IsSealed) { return(FixedLambdaFactory(metadata.Target ?? method.DeclaringType, metadata.Method ?? method.Name, signature)); } // dynamic but not that fast treatment for other stuff return(DynamicLambdaFactory(method, signature)); }