public object Invoke(IDataContext context, IList <object> sourceValues) { var key = new CacheKey(sourceValues.ToArrayEx(o => o == null ? null : o.GetType())); Func <object[], object> expression; lock (_expressionCache) { if (!_expressionCache.TryGetValue(key, out expression)) { try { _sourceValues = sourceValues; _parameters = new List <KeyValuePair <int, ParameterExpression> > { new KeyValuePair <int, ParameterExpression>(-1, DataContextParameter) }; _dataContext = context; expression = CreateDelegate(); _expressionCache[key] = expression; } finally { _lambdaParameter = null; _lambdaParameters.Clear(); _sourceValues = null; _parameters = null; _dataContext = null; } } } if (_isEmpty) { return(expression.Invoke(new object[] { context })); } return(expression.Invoke(BindingReflectionExtensions.InsertFirstArg(sourceValues, context))); }
private object InvokeMethodInternal(object target, string methodName, object[] args, Type[] typeArgs) { var type = target.GetType(); var argTypes = GetArgTypes(args); var key = new CacheKey(argTypes); Func <object[], object> result = null; lock (this) { if (type == _type) { TryGetValue(key, out result); } } if (result != null) { return(result(BindingReflectionExtensions.InsertFirstArg(args, target))); } List <MethodInfo> methods; if (methodName == ReflectionExtensions.IndexerName) { methods = new List <MethodInfo>(); foreach (var property in type.GetPropertiesEx(MemberFlags.Public | MemberFlags.Instance)) { if (property.GetIndexParameters().Length == args.Length) { methods.AddIfNotNull(property.GetGetMethod(true)); } } } else { methods = BindingReflectionExtensions.GetExtensionsMethods(methodName, BindingServiceProvider.ResourceResolver.GetKnownTypes()); foreach (var method in type.GetMethodsEx(MemberFlags.Public | MemberFlags.Instance)) { try { if (method.Name == methodName) { methods.AddIfNotNull(BindingReflectionExtensions.ApplyTypeArgs(method, typeArgs)); } } catch { ; } } } bool hasParams; var resultIndex = TrySelectMethod(methods, argTypes, (i, types) => types, out hasParams); if (resultIndex >= 0) { var method = methods[resultIndex]; var parameters = argTypes.Select(t => (Expression)Expression.Parameter(t)).ToList(); var argExpressions = ConvertParameters(method.GetParameters(), parameters, hasParams); parameters.Insert(0, Expression.Parameter(type)); var compile = Expression.Lambda(Expression.Call(parameters[0], method, argExpressions), parameters.Cast <ParameterExpression>()).Compile(); var methodInfo = compile.GetType().GetMethodEx(nameof(Action.Invoke), MemberFlags.Public | MemberFlags.Instance); if (methodInfo == null) { result = compile.DynamicInvoke; } else { var del = ServiceProvider.ReflectionManager.GetMethodDelegate(methodInfo); result = objects => del(compile, objects); } } lock (this) { _type = type; this[key] = result; } if (result == null) { throw BindingExceptionManager.InvalidBindingMember(target.GetType(), methodName); } return(result(BindingReflectionExtensions.InsertFirstArg(args, target))); }
public object SetValue(object src, object[] args) { return(_member.SetValue(src, BindingReflectionExtensions.InsertFirstArg(args ?? MugenMvvmToolkit.Empty.Array <object>(), _indexes))); }