示例#1
0
        static string GetTargetName(string wrapperMethodInfo, BaseReflectionHelperInterfaceWrapperSetting setting,
                                    MemberInfoKind kind, MemberInfo memberInfo)
        {
            var result = setting.GetName(wrapperMethodInfo, memberInfo);

            if (kind == MemberInfoKind.PropertyGetter && !result.Split('.').Last().StartsWith("get_"))
            {
                return("get_" + result);
            }
            if (kind == MemberInfoKind.PropertySetter && !result.Split('.').Last().StartsWith("set_"))
            {
                return("set_" + result);
            }
            return(result);
        }
示例#2
0
        internal override Delegate GetFallback(MemberInfoKind infoKind)
        {
            Delegate result = null;

            switch (infoKind)
            {
            case MemberInfoKind.Method:
                result = FallbackAction;
                break;

            case MemberInfoKind.PropertyGetter:
                result = GetterFallbackAction;
                break;

            case MemberInfoKind.PropertySetter:
                result = SetterFallbackAction;
                break;

            default:
                throw new ArgumentOutOfRangeException("infoKind", infoKind, null);
            }
            return(result ?? base.GetFallback(infoKind));
        }
示例#3
0
        bool PrepareFallback(TypeBuilder typeBuilder, MethodInfo wrapperMethodInfo, List <FieldInfo> ctorInfos, List <object> ctorArgs, BaseReflectionHelperInterfaceWrapperSetting setting, ILGenerator ilGenerator, MemberInfoKind infoKind, MethodInfo delegateInvoke, bool isStatic, MemberInfo baseInfo)
        {
            var fallbackMode = setting.GetFallbackMode(wrapperMethodInfo, baseInfo, tWrapper);

            if (fallbackMode == ReflectionHelperFallbackMode.Default)
            {
                fallbackMode = defaultFallbackMode;
            }
            if (fallbackMode == ReflectionHelperFallbackMode.AbortWrapping)
            {
                throw new MissingMemberException(String.Format("\r\nCannot bind the {0}.{1} with the source member\r\n", wrapperMethodInfo.DeclaringType, wrapperMethodInfo.Name));
            }
            var fallback = setting.GetFallback(infoKind);

            if (fallback == null)
            {
                if (fallbackMode != ReflectionHelperFallbackMode.ThrowNotImplementedException)
                {
                    throw new ArgumentException(String.Format("\r\nCannot bind the {0}.{1} with the source member.\r\nPlease check spelling or define the fallback method with the following signature: \r\n\t{2}.\r\n", wrapperMethodInfo.DeclaringType, wrapperMethodInfo.Name, delegateInvoke.ToString()));
                }
                if (!this.isStatic)
                {
                    ilGenerator.Emit(OpCodes.Pop);
                }
                ilGenerator.ThrowException(typeof(NotImplementedException));
                return(false);
            }
            var fallbackType = fallback.GetType();

            if (fallbackMode != ReflectionHelperFallbackMode.FallbackWithoutValidation)
            {
                var           fallbackInvoke     = fallbackType.GetMethod("Invoke");
                var           currentParameters  = fallbackInvoke.GetParameters();
                var           expectedParameters = delegateInvoke.GetParameters();
                StringBuilder exceptionBuilder   = new StringBuilder();
                exceptionBuilder.AppendFormat("\r\nFallback method for the {0}.{1} has incorrect signature.\r\nExpected: {2};\r\nBut was: {3}.", wrapperMethodInfo.DeclaringType, wrapperMethodInfo.Name, delegateInvoke.ToString(), fallbackInvoke.ToString());
                if (currentParameters.Length != expectedParameters.Length || !fallbackInvoke.ReturnType.IsAssignableFrom(delegateInvoke.ReturnType))
                {
                    throw new ArgumentException(exceptionBuilder.ToString() + "\r\n");
                }
                bool shouldThrow = false;
                for (int i = 0; i < currentParameters.Length; i++)
                {
                    var current  = currentParameters[i];
                    var expected = expectedParameters[i];
                    if (current.ParameterType.IsAssignableFrom(expected.ParameterType))
                    {
                        continue;
                    }
                    exceptionBuilder.AppendFormat("\r\n\tParameter at {0}:\r\n\t\tShould be assignable with: {1}\r\n\t\tBut was: {2}", i, expected.ParameterType, current.ParameterType);
                    shouldThrow = true;
                }
                if (shouldThrow)
                {
                    throw new ArgumentException(exceptionBuilder.ToString() + "\r\n");
                }
            }
            var fallbackField = typeBuilder.DefineField("field" + wrapperMethodInfo.Name + "fallback",
                                                        fallbackType, FieldAttributes.Private);

            ctorInfos.Add(fallbackField);
            ctorArgs.Add(fallback);
            Ldfld(ilGenerator, fallbackField);
            return(true);
        }
示例#4
0
        void DefineMethod(TypeBuilder typeBuilder, MethodInfo wrapperMethodInfo, MemberInfo baseMemberInfo,
                          List <FieldInfo> ctorInfos,
                          List <object> ctorArgs, Type sourceType, FieldBuilder sourceObjectField,
                          BaseReflectionHelperInterfaceWrapperSetting setting, MemberInfoKind method, bool isStatic)
        {
            var          sourceMethodIsInterface  = GetIsInterface(setting, wrapperMethodInfo.Name, baseMemberInfo ?? wrapperMethodInfo);
            var          sourceMethodName         = GetTargetName(wrapperMethodInfo.Name, setting, method, baseMemberInfo ?? wrapperMethodInfo);
            var          sourceMethodBindingFalgs = setting.GetBindingFlags(baseMemberInfo, wrapperMethodInfo) | (isStatic ? BindingFlags.Static : 0);
            var          sourceMethodInfo         = (sourceMethodIsInterface ? sourceType.GetInterfaces() : FlatternType(sourceType, false)).Select(x => GetMethod(x, sourceMethodName, sourceMethodBindingFalgs, wrapperMethodInfo)).FirstOrDefault(x => x != null);
            FieldBuilder fieldInfo = null;

            if (sourceMethodInfo != null)
            {
                fieldInfo = typeBuilder.DefineField("field" + wrapperMethodInfo.Name, sourceMethodInfo.GetType(),
                                                    FieldAttributes.Private);
                ctorInfos.Add(fieldInfo);
                ctorArgs.Add(sourceMethodInfo);
            }

            var parameterTypes    = wrapperMethodInfo.GetParameters().Select(x => x.ParameterType).ToArray();
            var genericParameters = wrapperMethodInfo.GetGenericArguments();
            var methodBuilder     = typeBuilder.DefineMethod(wrapperMethodInfo.Name,
                                                             MethodAttributes.Public | MethodAttributes.Virtual, wrapperMethodInfo.ReturnType,
                                                             parameterTypes);

            GenericTypeParameterBuilder[] genericParameterBuilders = null;
            if (genericParameters.Length > 0)
            {
                genericParameterBuilders =
                    methodBuilder.DefineGenericParameters(genericParameters.Select(x => x.Name).ToArray());
            }
            Type[] updatedParameterTypes = new Type[parameterTypes.Length];
            for (int i = 0; i < parameterTypes.Length; i++)
            {
                var currentType = parameterTypes[i];
                if (ShouldWrapType(currentType))
                {
                    updatedParameterTypes[i] = currentType.IsByRef ? tpObject : typeof(object);
                }
                else
                {
                    updatedParameterTypes[i] = currentType;
                }
            }
            var ilGenerator         = methodBuilder.GetILGenerator();
            var returnType          = wrapperMethodInfo.ReturnType;
            var wrapReturnType      = ShouldWrapType(returnType);
            var unwrappedReturnTupe = wrapReturnType ? typeof(object) : returnType;
            var useTuple            = false;
            var delegateType        = ReflectionHelper.MakeGenericDelegate(updatedParameterTypes, ref unwrappedReturnTupe,
                                                                           isStatic ? null : typeof(object), out useTuple);
            var          delegateInvoke    = delegateType.GetMethod("Invoke");
            LocalBuilder tupleLocalBuilder = null;

            if (useTuple)
            {
                tupleLocalBuilder = ilGenerator.DeclareLocal(unwrappedReturnTupe);
            }
            var fallbackMode = sourceMethodInfo == null;

            if (fallbackMode)
            {
                if (!PrepareFallback(typeBuilder, wrapperMethodInfo, ctorInfos, ctorArgs, setting, ilGenerator, method, delegateInvoke, isStatic, baseMemberInfo))
                {
                    ilGenerator.Emit(OpCodes.Ret);
                    return;
                }
            }
            else
            {
                ilGenerator.Emit(OpCodes.Ldarg_0);
                Ldfld(ilGenerator, fieldInfo);
                TypeOf(ilGenerator, sourceType);
                TypeOf(ilGenerator, delegateType);
                ilGenerator.Emit(useTuple ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
                var methodInfo = ReflectionHelperInterfaceWrapper.GetDelegateMethodInfo;
                if (genericParameters.Length > 0)
                {
                    ilGenerator.Emit(OpCodes.Ldc_I4, genericParameters.Length);
                    ilGenerator.Emit(OpCodes.Newarr, typeof(Type));
                    for (var i = 0; i < genericParameters.Length; i++)
                    {
                        ilGenerator.Emit(OpCodes.Dup);
                        ilGenerator.Emit(OpCodes.Ldc_I4, i);
                        TypeOf(ilGenerator, genericParameterBuilders[i]);
                        ilGenerator.Emit(OpCodes.Stelem_Ref);
                    }
                    methodInfo = ReflectionHelperInterfaceWrapper.GetGenericDelegateMethodInfo;
                }
                EmitCall(ilGenerator, OpCodes.Call, methodInfo, null);
            }
            if (!isStatic)
            {
                Ldfld(ilGenerator, sourceObjectField);
            }
            for (byte i = 0; i < updatedParameterTypes.Length; i++)
            {
                var paramType = updatedParameterTypes[i];
                if (parameterTypes[i] != updatedParameterTypes[i])
                {
                    ilGenerator.Emit(OpCodes.Ldarg, i + 1);
                    if (paramType.IsByRef)
                    {
                        LSTind(ilGenerator, paramType.GetElementType(), false);
                    }
                    EmitCall(ilGenerator, OpCodes.Call, ReflectionHelperInterfaceWrapper.UnwrapMethodInfo, null);
                }
                else
                {
                    ilGenerator.Emit(OpCodes.Ldarg, i + 1);
                    if (paramType.IsByRef)
                    {
                        LSTind(ilGenerator, paramType.GetElementType(), false);
                    }
                }
            }
            EmitCall(ilGenerator, OpCodes.Call, delegateInvoke, null);

            if (useTuple)
            {
                SyncTupleItems(updatedParameterTypes.Select((x, i) => new Tuple <int, Type, Type>(i, x, parameterTypes[i])).Where(x => x.Item2.IsByRef),
                               unwrappedReturnTupe, wrapperMethodInfo.ReturnType != typeof(void), ilGenerator, tupleLocalBuilder, typeBuilder);
            }
            if (wrapReturnType)
            {
                TypeOf(ilGenerator, returnType);
                EmitCall(ilGenerator, OpCodes.Call, ReflectionHelperInterfaceWrapper.WrapMethodInfo, null);
            }
            ilGenerator.Emit(OpCodes.Ret);

            typeBuilder.DefineMethodOverride(methodBuilder, wrapperMethodInfo);
        }
示例#5
0
        void DefineFieldGetterOrSetter(TypeBuilder typeBuilder, PropertyInfo propertyInfo, MethodInfo wrapperMethodInfo,
                                       List <FieldInfo> ctorInfos,
                                       List <object> ctorArgs, Type sourceType, FieldBuilder sourceObjectField,
                                       BaseReflectionHelperInterfaceWrapperSetting setting, MemberInfoKind method, bool isStatic)
        {
            var sourceFieldInfo =
                sourceType.GetField(GetTargetName(propertyInfo.Name, setting, MemberInfoKind.Method, propertyInfo),
                                    setting.GetBindingFlags(wrapperMethodInfo, propertyInfo) | (isStatic ? BindingFlags.Static : 0));
            FieldBuilder fieldInfo = null;

            if (sourceFieldInfo != null)
            {
                fieldInfo = typeBuilder.DefineField("field" + wrapperMethodInfo.Name, sourceFieldInfo.GetType(),
                                                    FieldAttributes.Private);
                ctorInfos.Add(fieldInfo);
                ctorArgs.Add(sourceFieldInfo);
            }

            var parameterTypes = wrapperMethodInfo.GetParameters().Select(x => x.ParameterType).ToArray();
            var methodBuilder  = typeBuilder.DefineMethod(wrapperMethodInfo.Name,
                                                          MethodAttributes.Public | MethodAttributes.Virtual, wrapperMethodInfo.ReturnType,
                                                          parameterTypes);
            var  ilGenerator = methodBuilder.GetILGenerator();
            var  returnType = wrapperMethodInfo.ReturnType;
            bool wrapReturnType = method == MemberInfoKind.PropertyGetter && ShouldWrapType(returnType);
            bool wrapParameterType = method == MemberInfoKind.PropertySetter && !wrapReturnType && ShouldWrapType(parameterTypes[0]);
            Type unwrappedReturnType, unwrappedParameterType;

            Type[] unwrappedParameterTypes = parameterTypes;
            unwrappedReturnType = wrapReturnType ? typeof(object) : returnType;
            if (wrapParameterType)
            {
                unwrappedParameterType  = sourceFieldInfo.FieldType;
                unwrappedParameterTypes = new Type[] { unwrappedParameterType };
            }
            else
            {
                unwrappedParameterType = null;
            }

            var useTuple     = false;
            var delegateType = ReflectionHelper.MakeGenericDelegate(unwrappedParameterTypes, ref unwrappedReturnType,
                                                                    isStatic ? null : typeof(object), out useTuple);
            var delegateInvoke = delegateType.GetMethod("Invoke");
            var fallbackMode   = sourceFieldInfo == null;

            if (fallbackMode)
            {
                if (!PrepareFallback(typeBuilder, wrapperMethodInfo, ctorInfos, ctorArgs, setting, ilGenerator, method, delegateInvoke, isStatic, propertyInfo))
                {
                    ilGenerator.Emit(OpCodes.Ret);
                    return;
                }
            }
            else
            {
                ilGenerator.Emit(OpCodes.Ldarg_0);
                Ldfld(ilGenerator, fieldInfo);
                TypeOf(ilGenerator, delegateType);
                TypeOf(ilGenerator, typeof(object));
                if (wrapParameterType || wrapReturnType)
                {
                    TypeOf(ilGenerator, typeof(object));
                }
                else
                {
                    TypeOf(ilGenerator, sourceFieldInfo.FieldType);
                }
                if (isStatic)
                {
                    ilGenerator.Emit(OpCodes.Ldc_I4_1);
                }
                else
                {
                    ilGenerator.Emit(OpCodes.Ldc_I4_0);
                }
                EmitCall(ilGenerator, OpCodes.Call,
                         method == MemberInfoKind.PropertyGetter
                        ? ReflectionHelperInterfaceWrapper.GetFieldGetterMethodInfo
                        : ReflectionHelperInterfaceWrapper.GetFieldSetterMethodInfo, null);
            }
            if (!isStatic)
            {
                Ldfld(ilGenerator, sourceObjectField);
            }
            for (byte i = 0; i < parameterTypes.Length; i++)
            {
                ilGenerator.Emit(OpCodes.Ldarg, i + 1);
                if (wrapParameterType)
                {
                    EmitCall(ilGenerator, OpCodes.Call, ReflectionHelperInterfaceWrapper.UnwrapMethodInfo, null);
                }
            }
            EmitCall(ilGenerator, OpCodes.Call, delegateInvoke, null);
            if (wrapReturnType)
            {
                TypeOf(ilGenerator, returnType);
                EmitCall(ilGenerator, OpCodes.Call, ReflectionHelperInterfaceWrapper.WrapMethodInfo, null);
            }
            ilGenerator.Emit(OpCodes.Ret);

            typeBuilder.DefineMethodOverride(methodBuilder, tWrapper.GetMethod(wrapperMethodInfo.Name));
        }
示例#6
0
 internal virtual Delegate GetFallback(MemberInfoKind kind)
 {
     return(null);
 }