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