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); }