Exemplo n.º 1
0
        private static void ProcessReflectedMemberInfo(FieldInfo field, ReflectedMemberAttribute attr)
        {
            MemberInfo info = null;

            if (attr.Type == null)
            {
                throw new ArgumentException("Reflected member info attributes require Type to be defined");
            }
            if (attr.Name == null)
            {
                throw new ArgumentException("Reflected member info attributes require Name to be defined");
            }
            switch (attr)
            {
            case ReflectedFieldInfoAttribute rfia:
                info = GetFieldPropRecursive(rfia.Type, rfia.Name,
                                             BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public,
                                             (type, name, bindingFlags) => type.GetField(name, bindingFlags));
                if (info == null)
                {
                    throw new ArgumentException($"Unable to find field {rfia.Type.FullName}#{rfia.Name}");
                }
                break;

            case ReflectedPropertyInfoAttribute rpia:
                info = GetFieldPropRecursive(rpia.Type, rpia.Name,
                                             BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public,
                                             (type, name, bindingFlags) => type.GetProperty(name, bindingFlags));
                if (info == null)
                {
                    throw new ArgumentException($"Unable to find property {rpia.Type.FullName}#{rpia.Name}");
                }
                break;

            case ReflectedMethodInfoAttribute rmia:
                if (rmia.Parameters != null)
                {
                    info = rmia.Type.GetMethod(rmia.Name,
                                               BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                                               null, CallingConventions.Any, rmia.Parameters, null);
                    if (info == null)
                    {
                        throw new ArgumentException(
                                  $"Unable to find method {rmia.Type.FullName}#{rmia.Name}({string.Join(", ", rmia.Parameters.Select(x => x.FullName))})");
                    }
                }
                else
                {
                    info = rmia.Type.GetMethod(rmia.Name,
                                               BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                    if (info == null)
                    {
                        throw new ArgumentException(
                                  $"Unable to find method {rmia.Type.FullName}#{rmia.Name}");
                    }
                }

                if (rmia.ReturnType != null && !rmia.ReturnType.IsAssignableFrom(((MethodInfo)info).ReturnType))
                {
                    throw new ArgumentException(
                              $"Method {rmia.Type.FullName}#{rmia.Name} has return type {((MethodInfo) info).ReturnType.FullName}, expected {rmia.ReturnType.FullName}");
                }
                break;
            }

            if (info == null)
            {
                throw new ArgumentException(
                          $"Unable to find member info for {attr.GetType().Name}[{attr.Type.FullName}#{attr.Name}");
            }
            field.SetValue(null, info);
        }
Exemplo n.º 2
0
        private static void ProcessReflectedField(FieldInfo field, ReflectedMemberAttribute attr)
        {
            MethodInfo delegateMethod = field.FieldType.GetMethod("Invoke");

            ParameterInfo[] parameters = delegateMethod.GetParameters();
            string          trueName   = attr.Name ?? field.Name;
            Type            trueType   = attr.Type;
            bool            isStatic;

            if (attr is ReflectedSetterAttribute)
            {
                if (delegateMethod.ReturnType != typeof(void) || (parameters.Length != 1 && parameters.Length != 2))
                {
                    throw new ArgumentOutOfRangeException(nameof(field),
                                                          "Delegate for setter must be an action with one or two arguments");
                }

                isStatic = parameters.Length == 1;
                if (trueType == null && isStatic)
                {
                    throw new ArgumentException("Static field setters need their type defined", nameof(field));
                }

                if (!isStatic && trueType == null)
                {
                    trueType = parameters[0].ParameterType;
                }
            }
            else if (attr is ReflectedGetterAttribute)
            {
                if (delegateMethod.ReturnType == typeof(void) || (parameters.Length != 0 && parameters.Length != 1))
                {
                    throw new ArgumentOutOfRangeException(nameof(field),
                                                          "Delegate for getter must be an function with one or no arguments");
                }

                isStatic = parameters.Length == 0;
                if (trueType == null && isStatic)
                {
                    throw new ArgumentException("Static field getters need their type defined", nameof(field));
                }

                if (!isStatic && trueType == null)
                {
                    trueType = parameters[0].ParameterType;
                }
            }
            else
            {
                throw new ArgumentException($"Field attribute type {attr.GetType().FullName} is invalid",
                                            nameof(field));
            }

            BindingFlags bindingFlags = (isStatic ? BindingFlags.Static : BindingFlags.Instance) |
                                        BindingFlags.NonPublic |
                                        BindingFlags.Public;
            FieldInfo sourceField = GetFieldPropRecursive(trueType, trueName, bindingFlags,
                                                          (a, b, c) => a.GetField(b, c));
            PropertyInfo sourceProperty =
                GetFieldPropRecursive(trueType, trueName, bindingFlags, (a, b, c) => a.GetProperty(b, c));

            if (sourceField == null && sourceProperty == null)
            {
                throw new ArgumentException(
                          $"Unable to find field or property for {trueName} in {trueType.FullName} or its base types",
                          nameof(field));
            }
            var  sourceType = sourceField?.FieldType ?? sourceProperty.PropertyType;
            bool isSetter   = attr is ReflectedSetterAttribute;

            if (sourceProperty != null && isSetter && !sourceProperty.CanWrite)
            {
                throw new InvalidOperationException(
                          $"Can't create setter for readonly property {trueName} in {trueType.FullName}");
            }

            if (sourceProperty != null && !isSetter && !sourceProperty.CanRead)
            {
                throw new InvalidOperationException(
                          $"Can't create getter for writeonly property {trueName} in {trueType.FullName}");
            }

            var dynMethod = new DynamicMethod((isSetter ? "set" : "get") + "_" + trueType.FullName + "." + trueName,
                                              delegateMethod.ReturnType, parameters.Select(x => x.ParameterType).ToArray(),
                                              typeof(ReflectedManager).Module, true);
            ILGenerator il = dynMethod.GetILGenerator();

            if (!isStatic)
            {
                EmitThis(il, parameters[0].ParameterType, trueType);
            }

            if (isSetter)
            {
                int val = isStatic ? 0 : 1;
                il.Emit(OpCodes.Ldarg, val);
                EmitCast(il, parameters[val].ParameterType, sourceType);
                if (sourceProperty != null)
                {
                    il.Emit(sourceProperty.SetMethod.IsStatic ? OpCodes.Call : OpCodes.Callvirt,
                            sourceProperty.SetMethod);
                }
                else
                {
                    il.Emit(isStatic ? OpCodes.Stsfld : OpCodes.Stfld, sourceField);
                }
            }
            else
            {
                if (sourceProperty != null)
                {
                    il.Emit(sourceProperty.GetMethod.IsStatic ? OpCodes.Call : OpCodes.Callvirt,
                            sourceProperty.GetMethod);
                }
                else
                {
                    il.Emit(isStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, sourceField);
                }
                EmitCast(il, sourceType, delegateMethod.ReturnType);
            }

            il.Emit(OpCodes.Ret);

            field.SetValue(null, dynMethod.CreateDelegate(field.FieldType));
            _log.Trace(
                $"Reflecting field {field.DeclaringType?.FullName}#{field.Name} with {field.DeclaringType?.FullName}#{field.Name}");
        }
Exemplo n.º 3
0
        private static void ProcessReflectedField(FieldInfo field, ReflectedMemberAttribute attr)
        {
            MethodInfo delegateMethod = field.FieldType.GetMethod("Invoke");

            ParameterInfo[] parameters = delegateMethod.GetParameters();
            string          trueName   = attr.Name ?? field.Name;
            Type            trueType   = attr.Type;
            bool            isStatic;

            if (attr is ReflectedSetterAttribute)
            {
                if (delegateMethod.ReturnType != typeof(void) || (parameters.Length != 1 && parameters.Length != 2))
                {
                    throw new ArgumentOutOfRangeException(nameof(field),
                                                          "Delegate for setter must be an action with one or two arguments");
                }

                isStatic = parameters.Length == 1;
                if (trueType == null && isStatic)
                {
                    throw new ArgumentException("Static field setters need their type defined", nameof(field));
                }

                if (!isStatic)
                {
                    trueType = parameters[0].ParameterType;
                }
            }
            else if (attr is ReflectedGetterAttribute)
            {
                if (delegateMethod.ReturnType == typeof(void) || (parameters.Length != 0 && parameters.Length != 1))
                {
                    throw new ArgumentOutOfRangeException(nameof(field),
                                                          "Delegate for getter must be an function with one or no arguments");
                }

                isStatic = parameters.Length == 0;
                if (trueType == null && isStatic)
                {
                    throw new ArgumentException("Static field getters need their type defined", nameof(field));
                }

                if (!isStatic)
                {
                    trueType = parameters[0].ParameterType;
                }
            }
            else
            {
                throw new ArgumentException($"Field attribute type {attr.GetType().FullName} is invalid", nameof(field));
            }

            BindingFlags bindingFlags = (isStatic ? BindingFlags.Static : BindingFlags.Instance) |
                                        BindingFlags.NonPublic |
                                        BindingFlags.Public;
            FieldInfo sourceField = GetFieldPropRecursive(trueType, trueName, bindingFlags,
                                                          (a, b, c) => a.GetField(b, c));
            PropertyInfo sourceProperty =
                GetFieldPropRecursive(trueType, trueName, bindingFlags, (a, b, c) => a.GetProperty(b, c));

            if (sourceField == null && sourceProperty == null)
            {
                throw new ArgumentException(
                          $"Unable to find field or property for {trueName} in {trueType.FullName} or its base types", nameof(field));
            }

            ParameterExpression[] paramExp = parameters.Select(x => Expression.Parameter(x.ParameterType)).ToArray();

            MemberExpression fieldExp = sourceField != null
                                            ? Expression.Field(isStatic?null : paramExp[0], sourceField)
                                            : Expression.Property(isStatic ? null : paramExp[0], sourceProperty);

            Expression impl;

            if (attr is ReflectedSetterAttribute)
            {
                impl = Expression.Block(Expression.Assign(fieldExp, paramExp[isStatic ? 0 : 1]), Expression.Default(typeof(void)));
            }
            else
            {
                impl = fieldExp;
            }

            field.SetValue(null, Expression.Lambda(impl, paramExp).Compile());
        }