Example #1
0
        public static ProxyGeneratorResult GenerateProxy(
            Type typeOfProxy,
            IFakeCallProcessorProvider fakeCallProcessorProvider)
        {
            Guard.AgainstNull(typeOfProxy, nameof(typeOfProxy));

            var invokeMethod = typeOfProxy.GetMethod("Invoke") !;

            if (!IsAccessibleToDynamicProxy(typeOfProxy))
            {
                try
                {
                    // This is the only way to get the proper error message.
                    // The need for this will go away when we start really using DynamicProxy to generate delegate proxies.
                    ProxyGenerator.CreateClassProxy(typeOfProxy);
                }
                catch (Exception ex)
                {
                    return(new ProxyGeneratorResult(ex.Message));
                }
            }

            var eventRaiser = new DelegateCallInterceptedEventRaiser(fakeCallProcessorProvider, invokeMethod, typeOfProxy);

            fakeCallProcessorProvider.EnsureInitialized(eventRaiser.Instance);
            return(new ProxyGeneratorResult(eventRaiser.Instance));
        }
        private static Delegate CreateDelegateProxy(
            Type typeOfProxy, MethodInfo invokeMethod, DelegateCallInterceptedEventRaiser eventRaiser)
        {
            var parameterExpressions =
                invokeMethod.GetParameters().Select(x => Expression.Parameter(x.ParameterType, x.Name)).ToArray();

            var body = CreateBodyExpression(invokeMethod, eventRaiser, parameterExpressions);
            return Expression.Lambda(typeOfProxy, body, parameterExpressions).Compile();
        }
Example #3
0
        private static Delegate CreateDelegateProxy(
            Type typeOfProxy, MethodInfo invokeMethod, DelegateCallInterceptedEventRaiser eventRaiser)
        {
            var parameterExpressions =
                invokeMethod.GetParameters().Select(x => Expression.Parameter(x.ParameterType, x.Name)).ToArray();

            var body = CreateBodyExpression(invokeMethod, eventRaiser, parameterExpressions);

            return(Expression.Lambda(typeOfProxy, body, parameterExpressions).Compile());
        }
        // Generate a method that:
        // - wraps its arguments in an object array
        // - passes this array to eventRaiser.Raise()
        // - assigns the output values back to the ref/out parameters
        // - casts and returns the result of eventRaiser.Raise()
        //
        // For instance, for a delegate like this:
        //
        // delegate int Foo(int x, ref int y, out int z);
        //
        // We generate a method like this:
        //
        // int ProxyFoo(int x, ref int y, out int z)
        // {
        //     var arguments = new[]{ (object)x, (object)y, (object)z };
        //     var result = (int)eventRaiser.Raise(arguments);
        //     y = (int)arguments[1];
        //     z = (int)arguments[2];
        //     return result;
        // }
        //
        // Or, for a delegate with void return type:
        //
        // delegate void Foo(int x, ref int y, out int z);
        //
        // void ProxyFoo(int x, ref int y, out int z)
        // {
        //     var arguments = new[]{ (object)x, (object)y, (object)z };
        //     eventRaiser.Raise(arguments);
        //     y = (int)arguments[1];
        //     z = (int)arguments[2];
        // }
        private static Expression CreateBodyExpression(
            MethodInfo delegateMethod,
            DelegateCallInterceptedEventRaiser eventRaiser,
            ParameterExpression[] parameterExpressions)
        {
            bool isVoid = delegateMethod.ReturnType == typeof(void);

            // Local variables of the generated method
            var arguments = Expression.Variable(typeof(object[]), "arguments");
            var result    = isVoid ? null : Expression.Variable(delegateMethod.ReturnType, "result");

            var bodyExpressions = new List <Expression>();

            bodyExpressions.Add(Expression.Assign(arguments, WrapParametersInObjectArray(parameterExpressions)));

            Expression call = Expression.Call(
                Expression.Constant(eventRaiser), DelegateCallInterceptedEventRaiser.RaiseMethod, arguments);

            if (!isVoid)
            {
                // If the return type is non void, cast the result of eventRaiser.Raise()
                // to the real return type and assign to the result variable
                call = Expression.Assign(result, Expression.Convert(call, delegateMethod.ReturnType));
            }

            bodyExpressions.Add(call);

            // After the call, copy the values back to the ref/out parameters
            for (int index = 0; index < parameterExpressions.Length; index++)
            {
                var parameter = parameterExpressions[index];
                if (parameter.IsByRef)
                {
                    var assignment = AssignParameterFromArrayElement(arguments, index, parameter);
                    bodyExpressions.Add(assignment);
                }
            }

            // Return the result if the return type is non-void
            if (!isVoid)
            {
                bodyExpressions.Add(result);
            }

            var variables = isVoid ? new[] { arguments } : new[] { arguments, result };

            return(Expression.Block(variables, bodyExpressions));
        }
Example #5
0
        public static ProxyGeneratorResult GenerateProxy(
            Type typeOfProxy,
            IFakeCallProcessorProvider fakeCallProcessorProvider)
        {
            Guard.AgainstNull(typeOfProxy, nameof(typeOfProxy));

            if (!CanGenerateProxy(typeOfProxy, out string reasonCannotGenerate))
            {
                return(new ProxyGeneratorResult(reasonCannotGenerate));
            }

            var invokeMethod = typeOfProxy.GetMethod("Invoke");
            var eventRaiser  = new DelegateCallInterceptedEventRaiser(fakeCallProcessorProvider, invokeMethod, typeOfProxy);

            fakeCallProcessorProvider.EnsureInitialized(eventRaiser.Instance);
            return(new ProxyGeneratorResult(eventRaiser.Instance));
        }
        private static Expression CreateBodyExpression(
            MethodInfo delegateMethod, DelegateCallInterceptedEventRaiser eventRaiser, IEnumerable<Expression> parameterExpressions)
        {
            var parameterExpressionsCastToObject =
                parameterExpressions.Select(x => Expression.Convert(x, typeof(object))).Cast<Expression>().ToArray();

            Expression body = Expression.Call(
                Expression.Constant(eventRaiser),
                DelegateCallInterceptedEventRaiser.RaiseMethod,
                new Expression[] { Expression.NewArrayInit(typeof(object), parameterExpressionsCastToObject) });

            if (!delegateMethod.ReturnType.Equals(typeof(void)))
            {
                body = Expression.Convert(body, delegateMethod.ReturnType);
            }

            return body;
        }
Example #7
0
        private static Expression CreateBodyExpression(
            MethodInfo delegateMethod, DelegateCallInterceptedEventRaiser eventRaiser, Expression[] parameterExpressions)
        {
            var parameterExpressionsCastToObject =
                parameterExpressions.Select(x => Expression.Convert(x, typeof(object))).Cast <Expression>().ToArray();

            Expression body = Expression.Call(
                Expression.Constant(eventRaiser),
                DelegateCallInterceptedEventRaiser.RaiseMethod,
                new Expression[] { Expression.NewArrayInit(typeof(object), parameterExpressionsCastToObject) });

            if (!delegateMethod.ReturnType.Equals(typeof(void)))
            {
                body = Expression.Convert(body, delegateMethod.ReturnType);
            }

            return(body);
        }
        public virtual ProxyGeneratorResult GenerateProxy(
            Type typeOfProxy,
            IEnumerable<Type> additionalInterfacesToImplement,
            IEnumerable<object> argumentsForConstructor,
            IFakeCallProcessorProvider fakeCallProcessorProvider)
        {
            Guard.AgainstNull(typeOfProxy, nameof(typeOfProxy));

            if (!typeof(Delegate).IsAssignableFrom(typeOfProxy))
            {
                return new ProxyGeneratorResult("The delegate proxy generator can only create proxies for delegate types.");
            }

            var invokeMethod = typeOfProxy.GetMethod("Invoke");
            var eventRaiser = new DelegateCallInterceptedEventRaiser(fakeCallProcessorProvider, invokeMethod, typeOfProxy);

            fakeCallProcessorProvider.EnsureInitialized(eventRaiser.Instance);
            return new ProxyGeneratorResult(eventRaiser.Instance);
        }
        public virtual ProxyGeneratorResult GenerateProxy(
            Type typeOfProxy,
            IEnumerable <Type> additionalInterfacesToImplement,
            IEnumerable <object> argumentsForConstructor,
            IFakeCallProcessorProvider fakeCallProcessorProvider)
        {
            Guard.AgainstNull(typeOfProxy, nameof(typeOfProxy));

            if (!typeof(Delegate).IsAssignableFrom(typeOfProxy))
            {
                return(new ProxyGeneratorResult("The delegate proxy generator can only create proxies for delegate types."));
            }

            var invokeMethod = typeOfProxy.GetMethod("Invoke");
            var eventRaiser  = new DelegateCallInterceptedEventRaiser(fakeCallProcessorProvider, invokeMethod, typeOfProxy);

            fakeCallProcessorProvider.EnsureInitialized(eventRaiser.Instance);
            return(new ProxyGeneratorResult(eventRaiser.Instance));
        }
        public virtual ProxyGeneratorResult GenerateProxy(Type typeOfProxy, IEnumerable<Type> additionalInterfacesToImplement,
                                                  IEnumerable<object> argumentsForConstructor)
        {
            if (!typeof (Delegate).IsAssignableFrom(typeOfProxy))
            {
                return
                    new ProxyGeneratorResult("The delegate proxy generator can only create proxies for delegate types.");
            }

            var invokeMethod = typeOfProxy.GetMethod("Invoke");

            var eventRaiser = new DelegateCallInterceptedEventRaiser();

            var proxy = CreateDelegateProxy(typeOfProxy, invokeMethod, eventRaiser);

            eventRaiser.Method = invokeMethod;
            eventRaiser.Instance = proxy;

            return new ProxyGeneratorResult(proxy, eventRaiser);
        }
Example #11
0
        public virtual ProxyGeneratorResult GenerateProxy(
            Type typeOfProxy, IEnumerable <Type> additionalInterfacesToImplement, IEnumerable <object> argumentsForConstructor)
        {
            if (!typeof(Delegate).IsAssignableFrom(typeOfProxy))
            {
                return
                    (new ProxyGeneratorResult("The delegate proxy generator can only create proxies for delegate types."));
            }

            var invokeMethod = typeOfProxy.GetMethod("Invoke");

            var eventRaiser = new DelegateCallInterceptedEventRaiser();

            var proxy = CreateDelegateProxy(typeOfProxy, invokeMethod, eventRaiser);

            eventRaiser.Method   = invokeMethod;
            eventRaiser.Instance = proxy;

            return(new ProxyGeneratorResult(proxy, eventRaiser));
        }
        public virtual ProxyGeneratorResult GenerateProxy(
            Type typeOfProxy,
            IEnumerable <Type> additionalInterfacesToImplement,
            IEnumerable <object> argumentsForConstructor,
            IEnumerable <Expression <Func <Attribute> > > attributes,
            IFakeCallProcessorProvider fakeCallProcessorProvider)
        {
            Guard.AgainstNull(typeOfProxy, nameof(typeOfProxy));

            if (!this.CanGenerateProxy(typeOfProxy, out string reasonCannotGenerate))
            {
                return(new ProxyGeneratorResult(reasonCannotGenerate));
            }

            var invokeMethod = typeOfProxy.GetMethod("Invoke");
            var eventRaiser  = new DelegateCallInterceptedEventRaiser(fakeCallProcessorProvider, invokeMethod, typeOfProxy);

            fakeCallProcessorProvider.EnsureInitialized(eventRaiser.Instance);
            return(new ProxyGeneratorResult(eventRaiser.Instance));
        }
        // Generate a method that:
        // - wraps its arguments in an object array
        // - passes this array to eventRaiser.Raise()
        // - assigns the output values back to the ref/out parameters
        // - casts and returns the result of eventRaiser.Raise()
        //
        // For instance, for a delegate like this:
        //
        // delegate int Foo(int x, ref int y, out int z);
        //
        // We generate a method like this:
        //
        // int ProxyFoo(int x, ref int y, out int z)
        // {
        //     var arguments = new[]{ (object)x, (object)y, (object)z };
        //     var result = (int)eventRaiser.Raise(arguments);
        //     y = (int)arguments[1];
        //     z = (int)arguments[2];
        //     return result;
        // }
        //
        // Or, for a delegate with void return type:
        //
        // delegate void Foo(int x, ref int y, out int z);
        //
        // void ProxyFoo(int x, ref int y, out int z)
        // {
        //     var arguments = new[]{ (object)x, (object)y, (object)z };
        //     eventRaiser.Raise(arguments);
        //     y = (int)arguments[1];
        //     z = (int)arguments[2];
        // }
        private static Expression CreateBodyExpression(
            MethodInfo delegateMethod,
            DelegateCallInterceptedEventRaiser eventRaiser,
            ParameterExpression[] parameterExpressions)
        {
            bool isVoid = delegateMethod.ReturnType == typeof(void);

            // Local variables of the generated method
            var arguments = Expression.Variable(typeof(object[]), "arguments");
            var result = isVoid ? null : Expression.Variable(delegateMethod.ReturnType, "result");

            var bodyExpressions = new List<Expression>();

            bodyExpressions.Add(Expression.Assign(arguments, WrapParametersInObjectArray(parameterExpressions)));

            Expression call = Expression.Call(
                Expression.Constant(eventRaiser), DelegateCallInterceptedEventRaiser.RaiseMethod, arguments);

            if (!isVoid)
            {
                // If the return type is non void, cast the result of eventRaiser.Raise()
                // to the real return type and assign to the result variable
                call = Expression.Assign(result, Expression.Convert(call, delegateMethod.ReturnType));
            }

            bodyExpressions.Add(call);

            // After the call, copy the values back to the ref/out parameters
            for (int index = 0; index < parameterExpressions.Length; index++)
            {
                var parameter = parameterExpressions[index];
                if (parameter.IsByRef)
                {
                    var assignment = AssignParameterFromArrayElement(arguments, index, parameter);
                    bodyExpressions.Add(assignment);
                }
            }

            // Return the result if the return type is non-void
            if (!isVoid)
            {
                bodyExpressions.Add(result);
            }

            var variables = isVoid ? new[] { arguments } : new[] { arguments, result };
            return Expression.Block(variables, bodyExpressions);
        }