private static object GetDynamicMember(object obj, string memberName)
        {
            var binder   = Binder.GetMember(CSharpBinderFlags.None, memberName, null, new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
            var callsite = CallSite <Func <CallSite, object, object> > .Create(binder);

            return(callsite.Target(callsite, obj));
        }
示例#2
0
        private static PropertyReader[] GetDynamicProperties(IDynamicMetaObjectProvider provider)
        {
            var metaObject = provider.GetMetaObject(Expression.Constant(provider));

            var memberNames = metaObject.GetDynamicMemberNames();             // may return property names as well as method names, etc.

            var result = new List <PropertyReader>();

            foreach (var name in memberNames)
            {
                try
                {
                    var argumentInfo = new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) };

                    var binder = Binder.GetMember(CSharpBinderFlags.None, name, provider.GetType(), argumentInfo);

                    var site = CallSite <Func <CallSite, object, object> > .Create(binder);

                    var value = site.Target(site, provider);                     // will throw if no valid property getter

                    result.Add(new PropertyReader
                    {
                        Name          = name,
                        DeclaringType = provider.GetType(),
                        Read          = o => value
                    });
                }
                catch (RuntimeBinderException)
                {
                }
            }

            return(result.ToArray());
        }
        public static Func <TObject, TProperty> Get <TObject, TProperty>(string memberName, object context = null)
        {
            var callSite = CallSite <Func <CallSite, TObject, object> > .Create(
                Binder.GetMember(CSharpBinderFlags.None, memberName, Context(context), new[] { Arg }));

            return(obj => (TProperty)callSite.Target(callSite, obj));
        }
示例#4
0
 private static object GetDynamically(MemberInfo member, object target)
 {
     var binder = Binder.GetMember(CSharpBinderFlags.None, member.Name, member.GetMemberType(),
                                                     new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
     var callsite = CallSite<Func<CallSite, object, object>>.Create(binder);
     return callsite.Target(callsite, target);
 }
示例#5
0
            public void Set(object target, object value)
            {
                switch (target)
                {
                case IDictionary d:
                    d[name] = value;
                    break;

                case IDictionary <string, object> d:
                    d[name] = value;
                    break;

                default:
                    var site = SetMemberSites.GetOrAdd(
                        System.Tuple.Create(target.GetType(), name),
                        t => CallSite <Func <CallSite, object, object, object> > .Create(
                            Binder.GetMember(
                                CSharpBinderFlags.None,
                                t.Item2,
                                t.Item1,
                                new[]
                    {
                        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
                    })));

                    site.Target(site, target, value);
                    break;
                }
            }
示例#6
0
        public TypeWrapper(Type type)
        {
            foreach (PropertyInfo p in type.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                string name = p.Name;
                CallSite <Action <CallSite, object, object> > set = CallSite <Action <CallSite, object, object> > .Create(
                    Binder.SetMember(
                        CSharpBinderFlags.None,
                        name,
                        type,
                        new[]
                {
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
                }));

                _setters.Add(name, set);

                CallSite <Func <CallSite, object, object> > get = CallSite <Func <CallSite, object, object> > .Create(
                    Binder.GetMember(
                        CSharpBinderFlags.None,
                        name,
                        type,
                        new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));

                _getters.Add(name, get);
            }
        }
示例#7
0
        protected object GetDynamically(MemberInfo member, object target)
        {
            var binder = Binder.GetMember(CSharpBinderFlags.None, member.Name, ReflectionHelper.GetMemberType(member),
                                          new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
            var callsite = CallSite <Func <CallSite, object, object> > .Create(binder);

            return(callsite.Target(callsite, target));
        }
示例#8
0
        public static Expression CompileGetMember(Expression target, string clientExpr)
        {
            var binder = DynamicBinder.GetMember(CSharpBinderFlags.None, clientExpr, typeof(DynamicBindingHelper), EMPTY_ARGUMENT_INFO);

            return(Expression.Call(
                       typeof(Utils).GetMethod(nameof(Utils.UnwrapNewtonsoftValue)),
                       DynamicExpression.Dynamic(binder, typeof(object), target)
                       ));
        }
示例#9
0
        public static T GetDynamicMemberValue <T>(this object obj, string name)
        {
            var dynamicObject = (DynamicJsonObject)obj;
            var binder        = Binder.GetMember(CSharpBinderFlags.None, name, obj.GetType(), new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
            var callsite      = CallSite <Func <CallSite, object, object> > .Create(binder);

            var value = callsite.Target(callsite, obj);

            return((T)value);
        }
示例#10
0
        public static Func <object, object> CallSiteBindGet(AccessorMember member)
        {
            var args = new List <CSharpArgumentInfo> {
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            };
            var binder   = Binder.GetMember(CSharpBinderFlags.None, member.Name, member.MemberInfo.DeclaringType, args);
            var callsite = CallSite <Func <CallSite, object, object> > .Create(binder);

            return(t => callsite.Target(callsite, t));
        }
        public static Expression CompileGetMember(Expression target, string clientExpr) {
            if(EMPTY_ARGUMENT_INFO == null)
                EMPTY_ARGUMENT_INFO = new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) };

            var binder = DynamicBinder.GetMember(CSharpBinderFlags.None, clientExpr, typeof(DynamicBindingHelper), EMPTY_ARGUMENT_INFO);

            return Expression.Call(
                typeof(Utils).GetMethod(nameof(Utils.UnwrapNewtonsoftValue)),
                DynamicExpression.Dynamic(binder, typeof(object), target)
            );
        }
            private static CallSite <Func <CallSite, object, object> > GetCallSiteLocked(string name)
            {
                var callSite = (CallSite <Func <CallSite, object, object> >)callSites[name];

                if (callSite == null)
                {
                    callSites[name] = callSite = CallSite <Func <CallSite, object, object> > .Create(
                        Binder.GetMember(CSharpBinderFlags.None, name, typeof(AccessorCache),
                                         new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
                }
                return(callSite);
            }
        /// <summary>Gets a value of a given property of a dynamic <paramref name="target" /> object.</summary>
        /// <param name="target">Target object .</param>
        /// <param name="propertyName">Property name to be get.</param>
        /// <returns>Value of the property.</returns>
        public static object InvokeGet(dynamic target, string propertyName)
        {
            int binderHash = propertyName.GetHashCode() ^ target.GetType().GetHashCode();
            CallSite <Func <CallSite, object, object> > callSite;

            if (!GetCallSites.TryGetValue(binderHash, out callSite))
            {
                var binder = Binder.GetMember(CSharpBinderFlags.None, propertyName, target.GetType(), InvokeGetArgs);
                GetCallSites[binderHash] = callSite = CallSite <Func <CallSite, object, object> > .Create(binder);
            }

            return(callSite.Target(callSite, target));
        }
示例#14
0
        internal static object InvokeGetCallSite(object target, string name, Type context, bool staticContext, ref CallSite callsite)
        {
            if (callsite == null)
            {
                var        tTargetFlag = CSharpArgumentInfoFlags.None;
                LazyBinder tBinder;
                Type       tBinderType;
                int        tKnownType;
                if (staticContext) //CSharp Binder won't call Static properties, grrr.
                {
                    var tStaticFlag = CSharpBinderFlags.None;
                    if (Util.IsMono) //Mono only works if InvokeSpecialName is set and .net only works if it isn't
                    {
                        tStaticFlag |= CSharpBinderFlags.InvokeSpecialName;
                    }

                    tBinder = () => Binder.InvokeMember(tStaticFlag, "get_" + name,
                                                        null,
                                                        context,
                                                        new List <CSharpArgumentInfo>
                    {
                        CSharpArgumentInfo.Create(
                            CSharpArgumentInfoFlags.IsStaticType |
                            CSharpArgumentInfoFlags.UseCompileTimeType,
                            null)
                    });

                    tBinderType = typeof(InvokeMemberBinder);
                    tKnownType  = KnownMember;
                }
                else
                {
                    tBinder = () => Binder.GetMember(CSharpBinderFlags.None, name,
                                                     context,
                                                     new List <CSharpArgumentInfo>
                    {
                        CSharpArgumentInfo.Create(
                            tTargetFlag, null)
                    });
                    tBinderType = typeof(GetMemberBinder);
                    tKnownType  = KnownGet;
                }


                callsite = CreateCallSite <Func <CallSite, object, object> >(tBinderType, tKnownType, tBinder, name, context,
                                                                             staticContext: staticContext);
            }
            var tCallSite = (CallSite <Func <CallSite, object, object> >)callsite;

            return(tCallSite.Target(tCallSite, target));
        }
示例#15
0
        public static Expression GetMember(Expression lhs, string memberName)
        {
            var binder = Binder.GetMember(
                CSharpBinderFlags.None,
                memberName,
                typeof(ExpandoObject),
                new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }
                );
            var member = Expression.Dynamic(binder, typeof(object), lhs);

#if DEBUG
            Debug.WriteLine(member);
#endif
            return(member);
        }
 private Expression ToExpression(ParameterExpression parameter, PropertyInfo property, ColumnDescription column)
 {
     if (property == null)
     {
         if (column.Name == table.DiscriminatorColumn)
         {
             return(Expression.Call(Expression.Constant(table), typeof(ObjectDataTable <T>).GetMethod(nameof(GetDiscriminator), BindingFlags.Instance | BindingFlags.NonPublic), parameter));
         }
         var binder = Binder.GetMember(CSharpBinderFlags.None, column.Name, typeof(ObjectData),
                                       new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
         var expression = Expression.Dynamic(binder, typeof(object), parameter);
         return(Expression.TryCatch(expression, Expression.Catch(typeof(RuntimeBinderException), Expression.Constant(null))));
     }
     return(Expression.Property(parameter, property));
 }
        internal static object InvokeGetCallSite(object target, string name, Type context, bool staticContext,
                                                 ref CallSite callsite)
        {
            if (callsite == null)
            {
                var        targeflag = CSharpArgumentInfoFlags.None;
                LazyBinder binder;
                Type       binderType;
                if (staticContext) //CSharp Binder won't call Static properties, grrr.
                {
                    var staticFlag = CSharpBinderFlags.None;
                    if (TypeFactorization.IsMonoRuntimeEnvironment)
                    {
                        //Mono only works if InvokeSpecialName is set and .net only works if it isn't
                        staticFlag |= CSharpBinderFlags.InvokeSpecialName;
                    }

                    binder = () => Binder.InvokeMember(staticFlag, "get_" + name,
                                                       null,
                                                       context,
                                                       new List <CSharpArgumentInfo>
                    {
                        CSharpArgumentInfo.Create(
                            CSharpArgumentInfoFlags.IsStaticType |
                            CSharpArgumentInfoFlags.UseCompileTimeType,
                            null)
                    });

                    binderType = typeof(InvokeMemberBinder);
                }
                else
                {
                    binder = () => Binder.GetMember(CSharpBinderFlags.None, name,
                                                    context,
                                                    new List <CSharpArgumentInfo>
                    {
                        CSharpArgumentInfo.Create(
                            targeflag, null)
                    });
                    binderType = typeof(GetMemberBinder);
                }

                callsite = CreateCallSite <Func <CallSite, object, object> >(binderType, binder, name, context);
            }
            var callSite = (CallSite <Func <CallSite, object, object> >)callsite;

            return(callSite.Target(callSite, target));
        }
        private static Func <object, object> CreateNewGetDelegate([NotNull] string property)
        {
            Debug.Assert(!string.IsNullOrEmpty(property), "property cannot be null or empty");

            var callSite = CallSite <Func <CallSite, object, object> > .Create(
                Binder.GetMember(
                    CSharpBinderFlags.None,
                    property,
                    typeof(SimpleDynamicInvoker),
                    new[]
            {
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            }));

            return(@object => callSite.Target(callSite, @object));
        }
示例#19
0
        private IQueryable <dynamic> Sort(IQueryable <dynamic> data, Type elementType, SortInfo sort)
        {
            Debug.Assert(data != null);

            if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(elementType))
            {
                // IDynamicMetaObjectProvider properties are only available through a runtime binder, so we
                // must build a custom LINQ expression for getting the dynamic property value.
                // Lambda: o => o.Property (where Property is obtained by runtime binder)
                // NOTE: lambda must not use internals otherwise this will fail in partial trust when Helpers assembly is in GAC
                var binder = Binder.GetMember(CSharpBinderFlags.None, sort.SortColumn, typeof(WebGrid), new[]
                {
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
                });
                var param  = Expression.Parameter(typeof(IDynamicMetaObjectProvider), "o");
                var getter = Expression.Dynamic(binder, typeof(object), param);
                return(SortGenericExpression <IDynamicMetaObjectProvider, object>(data, getter, param, sort.SortDirection));
            }
            else
            {
                // The IQueryable<dynamic> data source is cast as IQueryable<object> at runtime. We must call
                // SortGenericExpression using reflection so that the LINQ expressions use the actual element type.
                // Lambda: o => o.Property[.NavigationProperty,etc]
                var        param  = Expression.Parameter(elementType, "o");
                Expression member = param;
                var        type   = elementType;
                var        sorts  = sort.SortColumn.Split('.');
                foreach (var name in sorts)
                {
                    PropertyInfo prop = type.GetProperty(name);
                    if (prop == null)
                    {
                        // no-op in case navigation property came from querystring (falls back to default sort)
                        if ((DefaultSort != null) && !sort.Equals(DefaultSort) && !String.IsNullOrEmpty(DefaultSort.SortColumn))
                        {
                            return(Sort(data, elementType, DefaultSort));
                        }
                        return(data);
                    }
                    member = Expression.Property(member, prop);
                    type   = prop.PropertyType;
                }
                MethodInfo m = GetType().GetMethod("SortGenericExpression", BindingFlags.Static | BindingFlags.NonPublic);
                m = m.MakeGenericMethod(elementType, member.Type);
                return((IQueryable <dynamic>)m.Invoke(null, new object[] { data, member, param, sort.SortDirection }));
            }
        }
示例#20
0
        private static object GetObjectProperty(object target, string propertyName)
        {
            var targetContext  = GetTargetContext(target);
            var callSiteBinder = Binder.GetMember(CSharpBinderFlags.None, propertyName, targetContext, GetPropertyArgumentInfo);
            var callSite       = CallSite <Func <CallSite, object, object> > .Create(callSiteBinder);

            try
            {
                return(callSite.Target(callSite, target));
            }
            catch (RuntimeBinderException)
            {
                // Если заданного свойства не существует

                return(null);
            }
        }
示例#21
0
        public static Dictionary <string, object> GetDynamicMemberNameValueDictionary(this object obj)
        {
            var dynamicObject = (DynamicJsonObject)obj;
            var dictionary    = new Dictionary <string, object>();

            foreach (var name in dynamicObject.GetDynamicMemberNames())
            {
                var binder   = Binder.GetMember(CSharpBinderFlags.None, name, obj.GetType(), new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
                var callsite = CallSite <Func <CallSite, object, object> > .Create(binder);

                var value = callsite.Target(callsite, obj);

                dictionary.Add(name, value);
            }

            return(dictionary);
        }
示例#22
0
        private static Accessor GetDynamicObjectAcessor(Type type, string attributeName)
        {
            var getterBinder   = Binder.GetMember(CSharpBinderFlags.None, attributeName, type, new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
            var callsiteGetter = CallSite <Func <CallSite, object, object> > .Create(getterBinder);

            var setterBinder = Binder.SetMember(CSharpBinderFlags.None, attributeName, type, new[]
            {
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            });
            var callsiteSetter = CallSite <Func <CallSite, object, object, object> > .Create(setterBinder);

            return(new Accessor {
                Setter = (@object, value) => callsiteSetter.Target(callsiteSetter, @object, value),
                Getter = (@object) => callsiteGetter.Target(callsiteGetter, @object)
            });
        }
        private (bool Exists, object?Value) Get(object obj, string property)
        {
            switch (obj)
            {
            case IDynamicMetaObjectProvider dmop:
            {
                var expression  = Expression.Constant(dmop);
                var dmo         = dmop.GetMetaObject(expression);
                var memberNames = dmo.GetDynamicMemberNames().ToList();
                if (!memberNames.Contains(property))
                {
                    return(false, default);
                }

                var binder        = Binder.GetMember(CSharpBinderFlags.None, property, null, new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
                var getExpression = Expression.Lambda <Func <object> >(Expression.Dynamic(binder, typeof(object), Expression.Constant(dmop)));
                var result        = getExpression.Compile()();
                return(true, result);
            }
        internal static object GetValue(string name, object target)
        {
            var callSite = (CallSite <Func <CallSite, object, object> >)Getters[name];

            if (callSite != null)
            {
                return(callSite.Target(callSite, target));
            }
            var newSite = CallSite <Func <CallSite, object, object> > .Create(Binder.GetMember(CSharpBinderFlags.None, name, typeof(CallSiteCache), new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));

            lock (Getters)
            {
                callSite = (CallSite <Func <CallSite, object, object> >)Getters[name];
                if (callSite == null)
                {
                    Getters[name] = callSite = newSite;
                }
            }
            return(callSite.Target(callSite, target));
        }
示例#25
0
            public object Get(object target)
            {
                switch (target)
                {
                case IDictionary d:
                    return(d[name]);

                case IDictionary <string, object> d:
                    d.TryGetValue(name, out var result);
                    return(result);

                default:
                    var site = GetMemberSites.GetOrAdd(
                        System.Tuple.Create(target.GetType(), name),
                        t => CallSite <Func <CallSite, object, object> > .Create(
                            Binder.GetMember(
                                CSharpBinderFlags.None,
                                t.Item2,
                                t.Item1,
                                new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) })));

                    return(site.Target(site, target));
                }
            }
示例#26
0
        /// <summary>
        /// Gets a property of the dynamic object.
        /// </summary>
        /// <param name="source">Source object.</param>
        /// <param name="member">Member to retrieve.</param>
        /// <returns>The requested property value.</returns>
        /// <exception cref="ArgumentNullException">If source or member are null.</exception>
        public static object GetProperty(this object source, string member)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (member == null)
            {
                throw new ArgumentNullException("member");
            }

            Type scope    = source.GetType();
            var  provider = source as IDynamicMetaObjectProvider;

            if (provider != null)
            {
                var      objectType = typeof(object);
                var      cacheKey   = objectType.FullName + member;
                Delegate del;

                if (!_delegateCache.TryGetValue(cacheKey, out del))
                {
                    ParameterExpression param = Expression.Parameter(typeof(object));
                    DynamicMetaObject   mobj  = provider.GetMetaObject(param);
                    var binder               = (GetMemberBinder)Binder.GetMember(0, member, scope, new[] { CSharpArgumentInfo.Create(0, null) });
                    DynamicMetaObject ret    = mobj.BindGetMember(binder);
                    BlockExpression   final  = Expression.Block(Expression.Label(CallSiteBinder.UpdateLabel), ret.Expression);
                    LambdaExpression  lambda = Expression.Lambda(final, param);
                    del = lambda.Compile();
                    _delegateCache.TryAdd(cacheKey, del);
                }

                return(del.DynamicInvoke(source));
            }
            return(source.GetType().GetProperty(member, BindingFlags.Public | BindingFlags.Instance).GetValue(source, null));
        }
 public static CallSiteBinder GetFieldPropertyBinder(string name)
 {
     return(Binder.GetMember(CSharpBinderFlags.None, name, null, GetArgInfo(1)));
 }
示例#28
0
            private static Action <IInvocation> CompileInvoker(MethodInfo method)
            {
                var methodParameters    = method.GetParameters();
                var invocationParameter = Expression.Parameter(typeof(IInvocation), "invocation");

                var targetAndArgumentInfos = Pack(
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                    methodParameters.Select(
                        mp => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.NamedArgument, mp.Name))).ToArray();

                var targetAndArguments = Pack <Expression>(
                    Expression.Property(invocationParameter, invocationParameter.Type, "InvocationTarget"),
                    methodParameters.Select(
                        (mp, index) =>
                        Expression.Convert(
                            Expression.ArrayIndex(
                                Expression.Property(invocationParameter, invocationParameter.Type,
                                                    "Arguments"),
                                Expression.Constant(index)), mp.ParameterType))).ToArray();

                Expression body = null;

                if (method.IsSpecialName)
                {
                    if (method.Name.Equals("get_Item"))
                    {
                        body = Expression.Dynamic(
                            Binder.GetIndex(
                                CSharpBinderFlags.InvokeSpecialName,
                                typeof(object),
                                targetAndArgumentInfos),
                            typeof(object),
                            targetAndArguments);
                    }

                    if (body == null && method.Name.Equals("set_Item"))
                    {
                        var targetAndArgumentInfosWithoutTheNameValue = Pack(
                            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                            methodParameters.Select(
                                mp => mp.Name == "value" ? CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) : CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.NamedArgument, mp.Name)));

                        body = Expression.Dynamic(
                            Binder.SetIndex(
                                CSharpBinderFlags.InvokeSpecialName,
                                typeof(object),
                                targetAndArgumentInfosWithoutTheNameValue),
                            typeof(object),
                            targetAndArguments);
                    }

                    if (body == null && method.Name.StartsWith("get_"))
                    {
                        //  Build lambda containing the following call site:
                        //  (IInvocation invocation) => {
                        //      invocation.ReturnValue = (object) ((dynamic)invocation.InvocationTarget).{method.Name};
                        //  }
                        body = Expression.Dynamic(
                            Binder.GetMember(
                                CSharpBinderFlags.InvokeSpecialName,
                                method.Name.Substring("get_".Length),
                                typeof(object),
                                targetAndArgumentInfos),
                            typeof(object),
                            targetAndArguments);
                    }

                    if (body == null && method.Name.StartsWith("set_"))
                    {
                        body = Expression.Dynamic(
                            Binder.SetMember(
                                CSharpBinderFlags.InvokeSpecialName,
                                method.Name.Substring("set_".Length),
                                typeof(object),
                                targetAndArgumentInfos),
                            typeof(object),
                            targetAndArguments);
                    }
                }
                if (body == null)
                {
                    //  Build lambda containing the following call site:
                    //  (IInvocation invocation) => {
                    //      invocation.ReturnValue = (object) ((dynamic)invocation.InvocationTarget).{method.Name}(
                    //          {methodParameters[*].Name}: ({methodParameters[*].Type})invocation.Arguments[*],
                    //          ...);
                    //  }


                    body = Expression.Dynamic(
                        Binder.InvokeMember(
                            CSharpBinderFlags.None,
                            method.Name,
                            null,
                            typeof(object),
                            targetAndArgumentInfos),
                        typeof(object),
                        targetAndArguments);
                }

                if (method.ReturnType != typeof(void))
                {
                    body = Expression.Assign(
                        Expression.Property(invocationParameter, invocationParameter.Type, "ReturnValue"),
                        Expression.Convert(body, typeof(object)));
                }

                var lambda = Expression.Lambda <Action <IInvocation> >(body, invocationParameter);

                return(lambda.Compile());
            }
示例#29
0
        /// <summary>
        /// Returns an Expression that accesses a member on an Expression
        /// </summary>
        /// <param name="isFunction">Determines whether the member being accessed is a function or a property</param>
        /// <param name="isCall">Determines whether the member returns void</param>
        /// <param name="le">The expression that contains the member to be accessed</param>
        /// <param name="membername">The name of the member to access</param>
        /// <param name="args">Optional list of arguments to be passed if the member is a method</param>
        /// <returns></returns>
        public static Expression MemberAccess(bool isFunction, bool isCall, Expression le, string membername, List <Expression> args)
        {
            var argTypes = args.Select(x => x.Type);

            Expression instance = null;
            Type       type     = null;

            var isDynamic     = false;
            var isRuntimeType = false;

            if (le.Type.Name == "RuntimeType")
            {
                isRuntimeType = true;
                type          = ((Type)((ConstantExpression)le).Value);
            }
            else
            {
                type      = le.Type;
                instance  = le;
                isDynamic = type.IsDynamic();
            }

            if (isFunction)
            {
                if (isDynamic)
                {
                    var expArgs = new List <Expression> {
                        instance
                    };

                    expArgs.AddRange(args);

                    if (isCall)
                    {
                        var binderMC = Binder.InvokeMember(
                            CSharpBinderFlags.ResultDiscarded,
                            membername,
                            null,
                            type,
                            expArgs.Select(x => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null))
                            );

                        return(Expression.Dynamic(binderMC, typeof(void), expArgs));
                    }

                    var binderM = Binder.InvokeMember(
                        CSharpBinderFlags.None,
                        membername,
                        null,
                        type,
                        expArgs.Select(x => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null))
                        );

                    return(Expression.Dynamic(binderM, typeof(object), expArgs));
                }
                else
                {
                    var mis        = MethodResolution.GetApplicableMembers(type, membername, args);
                    var methodInfo = (MethodInfo)mis[0];

                    if (methodInfo != null)
                    {
                        var parameterInfos = methodInfo.GetParameters();

                        foreach (var parameterInfo in parameterInfos)
                        {
                            var index = parameterInfo.Position;

                            args[index] = TypeConversion.Convert(args[index], parameterInfo.ParameterType);
                        }

                        return(Expression.Call(instance, methodInfo, args.ToArray()));
                    }

                    var match = MethodResolution.GetExactMatch(type, instance, membername, args) ??
                                MethodResolution.GetParamsMatch(type, instance, membername, args);

                    if (match != null)
                    {
                        return(match);
                    }
                }
            }
            else
            {
                if (isDynamic)
                {
                    var binder = Binder.GetMember(
                        CSharpBinderFlags.None,
                        membername,
                        type,
                        new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }
                        );

                    var result = Expression.Dynamic(binder, typeof(object), instance);


                    if (args.Count > 0)
                    {
                        var expArgs = new List <Expression>()
                        {
                            result
                        };

                        expArgs.AddRange(args);

                        var indexedBinder = Binder.GetIndex(
                            CSharpBinderFlags.None,
                            type,
                            expArgs.Select(x => CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null))
                            );

                        result =
                            Expression.Dynamic(indexedBinder, typeof(object), expArgs);
                    }

                    return(result);
                }
                else
                {
                    Expression exp = null;

                    var propertyInfo = type.GetProperty(membername);
                    if (propertyInfo != null)
                    {
                        exp = Expression.Property(instance, propertyInfo);
                    }
                    else
                    {
                        var fieldInfo = type.GetField(membername);
                        if (fieldInfo != null)
                        {
                            exp = Expression.Field(instance, fieldInfo);
                        }
                    }

                    if (exp != null)
                    {
                        if (args.Count > 0)
                        {
                            return(Expression.ArrayAccess(exp, args));
                        }
                        else
                        {
                            return(exp);
                        }
                    }
                }
            }

            throw new Exception(string.Format("Member not found: {0}.{1}", le.Type.Name, membername));
        }
示例#30
0
        internal static object InvokeGetCallSite(object target, string name, Type context, bool staticContext, ref CallSite callsite)
        {
            if (callsite == null)
            {
                var        tTargetFlag = CSharpArgumentInfoFlags.None;
                LazyBinder tBinder;
                Type       tBinderType;
                int        tKnownType;
                if (staticContext) //CSharp Binder won't call Static properties, grrr.
                {
                    var tStaticFlag = CSharpBinderFlags.None;
                    if ((target is Type && ((Type)target).GetTypeInfo().IsPublic))
                    {
                        tBinder = () => Binder.InvokeMember(tStaticFlag, "get_" + name,
                                                            null,
                                                            context,
                                                            new List <CSharpArgumentInfo>
                        {
                            CSharpArgumentInfo.Create(
                                CSharpArgumentInfoFlags.IsStaticType |
                                CSharpArgumentInfoFlags.UseCompileTimeType,
                                null)
                        });

                        tBinderType = typeof(InvokeMemberBinder);
                        tKnownType  = KnownMember;
                    }
                    else
                    {
                        tBinder = () => Binder.GetMember(tStaticFlag, name,
                                                         context,
                                                         new List <CSharpArgumentInfo>
                        {
                            CSharpArgumentInfo.Create(
                                CSharpArgumentInfoFlags.IsStaticType, null)
                        });

                        tBinderType = typeof(InvokeMemberBinder);
                        tKnownType  = KnownMember;
                    }
                }
                else
                {
                    tBinder = () => Binder.GetMember(CSharpBinderFlags.None, name,
                                                     context,
                                                     new List <CSharpArgumentInfo>
                    {
                        CSharpArgumentInfo.Create(
                            tTargetFlag, null)
                    });
                    tBinderType = typeof(GetMemberBinder);
                    tKnownType  = KnownGet;
                }


                callsite = CreateCallSite <Func <CallSite, object, object> >(tBinderType, tKnownType, tBinder, name, context,
                                                                             staticContext: staticContext);
            }
            var tCallSite = (CallSite <Func <CallSite, object, object> >)callsite;

            return(tCallSite.Target(tCallSite, target));
        }