internal static object FromContinuationInfo(Type type, EventPromiseInfo promise, IStateObject source = null)
        {
            try
            {
                var    methodDeclaringType = TypeCacheUtils.GetType(promise.DeclaringType);
                object targetInstance      = null;

                Type[] types = Type.EmptyTypes;
                if (promise.MethodArgs != null)
                {
                    var typesNames = promise.MethodArgs.Split(PIPE_SEPARATOR, StringSplitOptions.RemoveEmptyEntries);
                    types = new Type[typesNames.Length];
                    int i = 0;
                    foreach (var typeName in typesNames)
                    {
                        types[i++] = TypeCacheUtils.GetType(typeName);
                    }
                }

                if (promise.isLocalInstance && source != null)
                {
                    targetInstance = source;
                }
                else
                {
                    var pointer = promise.ObjectContainingMethod as StateObjectPointerReference;
                    if (pointer != null)
                    {
                        targetInstance = pointer.Target;
                    }
                    else
                    {
                        targetInstance = promise.ObjectContainingMethod;
                    }
                }


                if (targetInstance is StateObjectSurrogate)
                {
                    targetInstance = ((StateObjectSurrogate)targetInstance).Value;
                }
                if (targetInstance == null)
                {
                    //Was this an static method?
                    if (promise.TargetType == null)
                    {
                        //Yes static
                        var staticType   = TypeCacheUtils.GetType(promise.DeclaringType);
                        var staticmethod = staticType.GetMethod(promise.MethodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                        return(Delegate.CreateDelegate(type, staticmethod));
                    }
                    else
                    {
                        //Ok, it was a not an IStateObject object. It might have been
                        //a delegate from another class
                        //So we need to instantiate it and set it to targetInstance
                        var targetType = TypeCacheUtils.GetType(promise.TargetType);
                        targetInstance = Activator.CreateInstance(targetType);
                        if (promise.ContinuationFields != null)
                        {
                            //Pending Restore state
                        }
                    }
                }
                else
                {
                    //First check if method was on this targetInstance. Why not? Because it could have been on a form

                    if (typeof(ILogicView <IViewModel>).IsAssignableFrom(methodDeclaringType))
                    {
                        var instanceWithMethodDeclaredType = TypeCacheUtils.GetType(promise.TargetType);
                        var form = IocContainerImplWithUnity.Current.Resolve(instanceWithMethodDeclaredType, parameters: new object[] { (IViewModel)targetInstance });
                        targetInstance = form;
                    }
                }
                var method = methodDeclaringType.GetMethod(promise.MethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, new ReflectionBinderForPromisesResolution(), types, null);
                //If type is delegate then we must build a generic delegate from Action<> or Func<> helpers
                if (typeof(Delegate) == type)
                {
                    Type methodDelegateType = TypeCacheUtils.GetDelegateTypeBasedOnMethodParameters(method);
                    return(Delegate.CreateDelegate(methodDelegateType, targetInstance, method));
                }
                return(Delegate.CreateDelegate(type, targetInstance, method));
            }
            catch (Exception ex)
            {
                TraceUtil.TraceError("ViewManager::PromiseUtils::FromContinuationInfo error while trying to restore delegate from continuation " + ex.Message);
            }
            return(null);
        }
Пример #2
0
        internal static EventPromiseInfo BuildContinuationInfo(StateManager stateManager, EventPromiseInfo promise, Delegate code, IStateObject parent = null, string promiseUniqueId = null, string actionID = "")
        {
            var  instance        = code.Target;
            Type codePromiseType = instance != null?instance.GetType() : null;

            string internalFieldsState = null;

            //This variable holds the reference
            //to the IStateObject that is closest to the promise.
            //For example if we are referring to a method on a Form. The closest state object is a
            //ViewModel. If the object is a DisplayClass, then we try to determine
            //which was the closest IModel or IUserControl where this DisplayClass was used
            IStateObject objectContainingMethod = null;

            if (codePromiseType != null)
            {
                //For special classes it's required to register a surrogate to save the application state.
                if (TypeCacheUtils.IsSpecialClass(codePromiseType))
                {
                    PromiseUtils.RegisterSurrogateForDisplayClass(codePromiseType, code.Target);
                    objectContainingMethod = stateManager.surrogateManager.GetSurrogateFor(code.Target, generateIfNotFound: true);
                }
                else
                {
                    var stateObject = instance as IStateObject;
                    if (stateObject != null)
                    {
                        objectContainingMethod = stateObject;
                    }
                    else
                    {
                        var logicView = instance as ILogicView <IViewModel>;
                        if (logicView != null)
                        {
                            objectContainingMethod = logicView.ViewModel;
                        }
                    }
                }
            }

            string methodArgs = null;
            var    parameters = code.Method.GetParameters();

            if (parameters.Length > 0)
            {
                StringBuilder builder = new StringBuilder();
                foreach (var parameter in parameters)
                {
                    builder.Append(parameter.ParameterType.AssemblyQualifiedNameCache());
                    builder.Append("|");
                }
                methodArgs = builder.ToString();
            }

            promise.DeclaringType = code.Method.DeclaringType.AssemblyQualifiedNameCache();
            //promise.SetObjectContainingMethod(objectContainingMethod);
            promise.TargetType = code.Target != null?code.Target.GetType().AssemblyQualifiedNameCache() : null;

            promise.MethodName = code.Method.Name;
            promise.ActionID   = actionID;
            promise.ParentId   = parent != null ? parent.UniqueID :
                                 promise.ModalUniqueId = null;
            promise.MethodArgs = methodArgs;
            promise.UniqueID   = promiseUniqueId ??
                                 (parent == null
                                   ? stateManager.UniqueIDGenerator.GetPromiseUniqueID()
                                   : stateManager.UniqueIDGenerator.GetRelativeUniqueID(parent));
            promise.ContinuationFields = internalFieldsState;
            promise.DelegateType       =
                TypeCacheUtils.GetDelegateTypeBasedOnMethodParameters(code.Method).AssemblyQualifiedNameCache();

            stateManager.AddNewObject(promise);

            if (objectContainingMethod != null)
            {
                if (!StateManager.AllBranchesAttached(objectContainingMethod))
                {
                    stateManager.AdoptionInformation.RegisterPossibleOrphan(promise, objectContainingMethod);
                }

                var referenceToObjectContainingMethod = new StateObjectPointerReference();
                var relativeUid = UniqueIDGenerator.GetPointerRelativeUniqueID(promise, "PO");
                LazyBehaviours.AddDependent(promise, UniqueIDGenerator.REFERENCEPrefix + "PO");
                StateObjectPointer.AssignUniqueIdToPointer(promise, relativeUid, referenceToObjectContainingMethod);
                referenceToObjectContainingMethod.Target = objectContainingMethod;
                stateManager.isServerSideOnly.Add(referenceToObjectContainingMethod);
                stateManager.AddNewObject(referenceToObjectContainingMethod);
                stateManager.ReferencesManager.AddReference(referenceToObjectContainingMethod, objectContainingMethod);
                var surrogate = objectContainingMethod as StateObjectSurrogate;
                if (surrogate != null)
                {
                    stateManager.surrogateManager.AddSurrogateReference(surrogate, referenceToObjectContainingMethod);
                }

                promise.SetObjectContainingMethod(referenceToObjectContainingMethod);
            }
            if (parent != null && objectContainingMethod != null && parent.Equals(objectContainingMethod))
            {
                promise.isLocalInstance = true;
            }
            else
            if (promiseUniqueId != null && objectContainingMethod != null)
            {
                var parentUniqueID = StateManager.GetLastPartOfUniqueID(promise);
                promise.isLocalInstance = string.Equals(parentUniqueID, objectContainingMethod.UniqueID);
            }

            return(promise);
        }
        internal static Delegate CreateDelegateFromMethodInfo(object target, MethodInfo methodInfo)
        {
            Type delegateType = TypeCacheUtils.GetDelegateTypeBasedOnMethodParameters(methodInfo);

            return(Delegate.CreateDelegate(delegateType, target, methodInfo, true));
        }