CallbackWrapper.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 / Runtime / CallbackWrapper.cs / 1305376 / CallbackWrapper.cs

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

namespace System.Activities.Runtime 
{
    using System; 
    using System.Reflection; 
    using System.Runtime.Serialization;
    using System.Diagnostics.CodeAnalysis; 
    using System.Runtime;
    using System.Security;
    using System.Security.Permissions;
 
    [DataContract]
    class CallbackWrapper 
    { 
        static BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Static;
 
        [DataMember]
        string callbackName;

        [DataMember(EmitDefaultValue = false)] 
        string declaringAssemblyName;
 
        [DataMember(EmitDefaultValue = false)] 
        string declaringTypeName;
 
        Delegate callback;

        public CallbackWrapper(Delegate callback, ActivityInstance owningInstance)
        { 
            this.ActivityInstance = owningInstance;
            this.callback = callback; 
        } 

        [DataMember] 
        public ActivityInstance ActivityInstance
        {
            get;
            private set; 
        }
 
        protected bool IsCallbackNull 
        {
            get 
            {
                return this.callback == null && this.callbackName == null;
            }
        } 

        protected Delegate Callback 
        { 
            get
            { 
                return this.callback;
            }
        }
 
        public static bool IsValidCallback(Delegate callback, ActivityInstance owningInstance)
        { 
            Fx.Assert(callback != null, "This should only be called with non-null callbacks"); 

            object target = callback.Target; 

            // if the target is null, it is static
            if (target == null)
            { 
                Fx.Assert(callback.Method.IsStatic, "This method should be static when target is null");
                return true; 
            } 

            // its owner's activity 
            if (object.ReferenceEquals(target, owningInstance.Activity))
            {
                return true;
            } 

            return false; 
        } 

        protected void EnsureCallback(Type delegateType, Type[] parameterTypes, Type genericParameter) 
        {
            // We were unloaded and have some work to do to rebuild the callback
            if (this.callback == null)
            { 
                this.callback = GenerateCallback(delegateType, parameterTypes, genericParameter);
                Fx.Assert(this.callback != null, "GenerateCallback should have been able to produce a non-null callback."); 
            } 
        }
 
        protected void ValidateCallbackResolution(Type delegateType, Type[] parameterTypes, Type genericParameter)
        {
            Fx.Assert(this.callback != null && this.callbackName != null, "We must have a callback and a callback name");
 
            if (!this.callback.Equals(GenerateCallback(delegateType, parameterTypes, genericParameter)))
            { 
                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.InvalidExecutionCallback(this.callback.Method, null))); 
            }
        } 

        Delegate GenerateCallback(Type delegateType, Type[] parameterTypes, Type genericParameter)
        {
            Type declaringType; 
            MethodInfo methodInfo = GetMatchingMethod(parameterTypes, out declaringType);
 
            if (methodInfo == null) 
            {
                MethodInfo[] potentialMatches = declaringType.GetMethods(bindingFlags); 

                for (int i = 0; i < potentialMatches.Length; i++)
                {
                    MethodInfo potentialMatch = potentialMatches[i]; 

                    if (potentialMatch.IsGenericMethod && potentialMatch.Name == this.callbackName) 
                    { 
                        Fx.Assert(potentialMatch.IsGenericMethodDefinition, "We should be getting the generic method definition here.");
 
                        Type[] genericArguments = potentialMatch.GetGenericArguments();

                        if (genericArguments.Length == 1)
                        { 
                            potentialMatch = potentialMatch.MakeGenericMethod(genericParameter);
 
                            ParameterInfo[] parameters = potentialMatch.GetParameters(); 

                            bool match = true; 
                            for (int parameterIndex = 0; parameterIndex < parameters.Length; parameterIndex++)
                            {
                                ParameterInfo parameter = parameters[parameterIndex];
 
                                if (parameter.IsOut || parameter.IsOptional || parameter.ParameterType != parameterTypes[parameterIndex])
                                { 
                                    match = false; 
                                    break;
                                } 
                            }

                            if (match)
                            { 
                                methodInfo = potentialMatch;
                                break; 
                            } 
                        }
                    } 
                }
            }

            if (methodInfo == null) 
            {
                return null; 
            } 

            return RecreateCallback(delegateType, methodInfo); 
        }

        protected void EnsureCallback(Type delegateType, Type[] parameters)
        { 
            // We were unloaded and have some work to do to rebuild the callback
            if (this.callback == null) 
            { 
                Type unusedDeclaringType;
                MethodInfo methodInfo = GetMatchingMethod(parameters, out unusedDeclaringType); 

                Fx.Assert(methodInfo != null, "We must have a method info by now");

                this.callback = RecreateCallback(delegateType, methodInfo); 
            }
        } 
 
        MethodInfo GetMatchingMethod(Type[] parameters, out Type declaringType)
        { 
            Fx.Assert(this.callbackName != null, "This should only be called when there is actually a callback to run.");

            object targetInstance = this.ActivityInstance.Activity;
 
            if (this.declaringTypeName == null)
            { 
                declaringType = targetInstance.GetType(); 
            }
            else 
            {
                // make a MethodInfo since it's not hanging directly off of our activity type
                Assembly callbackAssembly;
                if (this.declaringAssemblyName != null) 
                {
                    callbackAssembly = Assembly.Load(this.declaringAssemblyName); 
                } 
                else
                { 
                    callbackAssembly = targetInstance.GetType().Assembly;
                }

                declaringType = callbackAssembly.GetType(this.declaringTypeName); 
            }
 
            Fx.Assert(declaringType != null, "declaring type should be re-constructable from our serialized components"); 

            return declaringType.GetMethod(this.callbackName, bindingFlags, null, parameters, null); 
        }

        Delegate RecreateCallback(Type delegateType, MethodInfo callbackMethod)
        { 
            object targetInstance = null;
 
            if (!callbackMethod.IsStatic) 
            {
                targetInstance = this.ActivityInstance.Activity; 
            }

            return Delegate.CreateDelegate(delegateType, targetInstance, callbackMethod);
        } 

        [OnSerializing] 
        [SuppressMessage(FxCop.Category.Usage, FxCop.Rule.ReviewUnusedParameters)] 
        void OnSerializing(StreamingContext context)
        { 
            if (this.callbackName == null && !this.IsCallbackNull)
            {
                MethodInfo method = this.callback.Method;
                this.callbackName = method.Name; 
                Type declaringType = method.DeclaringType;
                Type activityType = this.ActivityInstance.Activity.GetType(); 
 
                if (declaringType != activityType)
                { 
                    // If we're not directly off of the Activity type being used,
                    // then we need to store the declaringType's name.
                    this.declaringTypeName = declaringType.FullName;
 
                    if (declaringType.Assembly != activityType.Assembly)
                    { 
                        this.declaringAssemblyName = declaringType.Assembly.FullName; 
                    }
                } 

                if (method.IsGenericMethod)
                {
                    OnSerializingGenericCallback(); 
                }
            } 
        } 

        protected virtual void OnSerializingGenericCallback() 
        {
            // Generics are invalid by default
            throw FxTrace.Exception.AsError(new InvalidOperationException(SR.InvalidExecutionCallback(this.callback.Method, null)));
        } 
    }
} 

// 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