MethodExecutor.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.Activities / System / Activities / Statements / MethodExecutor.cs / 1305376 / MethodExecutor.cs

                            //---------------------------------------------------------------- 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//---------------------------------------------------------------

namespace System.Activities.Statements 
{
    using System; 
    using System.Collections.ObjectModel; 
    using System.Diagnostics.CodeAnalysis;
    using System.Reflection; 
    using System.Runtime;

    // Inverted Template Method pattern. MethodExecutor is the base class for executing a method; created by MethodResolver.
    // Private concrete implementations are created by MethodResolver, but this is the "public" API used by InvokeMethod. 
    abstract class MethodExecutor
    { 
        // Used for creating tracing messages w/ DisplayName 
        Activity invokingActivity;
 
        // We may still need to know targetType if we're autocreating targets during ExecuteMethod
        Type targetType;
        InArgument targetObject;
        Collection parameters; 
        RuntimeArgument returnObject;
 
        public MethodExecutor(Activity invokingActivity, Type targetType, InArgument targetObject, 
            Collection parameters, RuntimeArgument returnObject)
        { 
            Fx.Assert(invokingActivity != null, "Must provide invokingActivity");
            Fx.Assert(targetType != null || (targetObject != null), "Must provide targetType or targetObject");
            Fx.Assert(parameters != null, "Must provide parameters");
            // returnObject is optional 

            this.invokingActivity = invokingActivity; 
            this.targetType = targetType; 
            this.targetObject = targetObject;
            this.parameters = parameters; 
            this.returnObject = returnObject;
        }

        public abstract bool MethodIsStatic { get; } 

        protected abstract IAsyncResult BeginMakeMethodCall(AsyncCodeActivityContext context, object target, AsyncCallback callback, object state); 
        protected abstract void EndMakeMethodCall(AsyncCodeActivityContext context, IAsyncResult result); 

        static bool HaveParameterArray(ParameterInfo[] parameters) 
        {
            if (parameters.Length > 0)
            {
                ParameterInfo last = parameters[parameters.Length - 1]; 
                return last.GetCustomAttributes(typeof(ParamArrayAttribute), true).GetLength(0) > 0;
            } 
            else 
            {
                return false; 
            }
        }

        protected object[] EvaluateAndPackParameters(CodeActivityContext context, MethodInfo method, 
            bool usingAsyncPattern)
        { 
            ParameterInfo[] formalParameters = method.GetParameters(); 
            int formalParamCount = formalParameters.Length;
            object[] actualParameters = new object[formalParamCount]; 

            if (usingAsyncPattern)
            {
                formalParamCount -= 2; 
            }
 
            bool haveParameterArray = HaveParameterArray(formalParameters); 
            for (int i = 0; i < formalParamCount; i++)
            { 
                if (i == formalParamCount - 1 && !usingAsyncPattern && haveParameterArray)
                {
                    int paramArrayCount = this.parameters.Count - formalParamCount + 1;
 
                    // If params are given explicitly, that's okay.
                    if (paramArrayCount == 1 && TypeHelper.AreTypesCompatible(this.parameters[i].ArgumentType, 
                        formalParameters[i].ParameterType)) 
                    {
                        actualParameters[i] = this.parameters[i].Get(context); 
                    }
                    else
                    {
                        // Otherwise, pack them into an array for the reflection call. 
                        actualParameters[i] =
                            Activator.CreateInstance(formalParameters[i].ParameterType, paramArrayCount); 
                        for (int j = 0; j < paramArrayCount; j++) 
                        {
                            ((object[])actualParameters[i])[j] = this.parameters[i + j].Get(context); 
                        }
                    }
                    continue;
                } 
                actualParameters[i] = parameters[i].Get(context);
            } 
 
            return actualParameters;
        } 

        [SuppressMessage(FxCop.Category.Usage, FxCop.Rule.InstantiateArgumentExceptionsCorrectly, Justification = "TargetObject is a parameter to InvokeMethod, rather than this specific method.")]
        public IAsyncResult BeginExecuteMethod(AsyncCodeActivityContext context, AsyncCallback callback, object state)
        { 
            object targetInstance = null;
 
            if(!this.MethodIsStatic) 
            {
                targetInstance = this.targetObject.Get(context); 
                if(targetInstance == null)
                {
                    throw FxTrace.Exception.ArgumentNull("TargetObject");
                } 
            }
 
            return BeginMakeMethodCall(context, targetInstance, callback, state); // defer to concrete instance for [....]/async variations 
        }
 
        public void EndExecuteMethod(AsyncCodeActivityContext context, IAsyncResult result)
        {
            EndMakeMethodCall(context, result); // defer to concrete instance for [....]/async variations
        } 

        internal object InvokeAndUnwrapExceptions(MethodInfo methodToInvoke, object targetInstance, object[] actualParameters) 
        { 
            try
            { 
                return methodToInvoke.Invoke(targetInstance, actualParameters);
            }
            catch (TargetInvocationException e)
            { 
                Fx.Assert(e.InnerException != null, "Should only get TargetInvocationExceptions that were caused by other exceptions inside the method.");
                if (TD.InvokedMethodThrewExceptionIsEnabled()) 
                { 
                    Exception inner = e.InnerException;
                    TD.InvokedMethodThrewException(this.invokingActivity.DisplayName, inner.ToString()); 
                }
                throw FxTrace.Exception.AsError(e.InnerException);
            }
        } 

        public void SetOutArgumentAndReturnValue(ActivityContext context, object state, object[] actualParameters) 
        { 
            for (int index = 0; index < parameters.Count; index++)
            { 
                if (parameters[index].Direction != ArgumentDirection.In)
                {
                    parameters[index].Set(context, actualParameters[index]);
                } 
            }
 
            if (this.returnObject != null) 
            {
                this.returnObject.Set(context, state); 
            }
        }

        public void Trace(Activity parent) 
        {
            if (this.MethodIsStatic) 
            { 
                if (TD.InvokeMethodIsStaticIsEnabled())
                { 
                    TD.InvokeMethodIsStatic(parent.DisplayName);
                }
            }
            else 
            {
                if (TD.InvokeMethodIsNotStaticIsEnabled()) 
                { 
                    TD.InvokeMethodIsNotStatic(parent.DisplayName);
                } 
            }
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK