private Delegate PublishInternal(EventPromiseInfo eventHandlerInfo, string eventId, IStateObject source, bool doNotCall, params object[] args)
        {
            var      delegateType  = TypeCacheUtils.GetType(eventHandlerInfo.DelegateType);
            Delegate eventDelegate = PromiseUtils.FromContinuationInfo(delegateType, eventHandlerInfo, source) as Delegate;

            if (eventDelegate == null)
            {
                TraceUtil.TraceError("EventAggregator::PublishInternal Error publishing event. Continuation could not be restored");
                return(null);
            }
            if (doNotCall)
            {
                return(eventDelegate);
            }
            TraceUtil.TraceInformation("Publishing event " + eventId);
            if (eventDelegate != null)
            {
                try
                {
                    eventDelegate.Method.Invoke(eventDelegate.Target, args);
                }
                catch (TargetInvocationException tiex)
                {
                    var baseException = tiex.GetBaseException();
                    PreserveStackTrace(baseException);
                    throw baseException;
                }
            }
            return(eventDelegate);
        }
        private void RegisterMethodForEvent(ILogic logic, MethodInfo method, string componentName, string eventId, IStateObject component)
        {
            var parameters = method.GetParameters();

            Debug.Assert(component != null,
                         "Invalid AutoWire for event handler " + method.Name + " component " + componentName + " was not found in viewmodel. Logic Type [ " + logic.GetType() + "]");
            if (component != null)
            {
                Subscribe(eventId, component, PromiseUtils.CreateDelegateFromMethodInfo(logic, method));
            }
        }
        public T PublishDelegate <T>(string eventId)
        {
            Delegate result = null;

            var eventHandlerInfo = _stateManager.GetObject(eventId) as EventPromiseInfo;

            if (eventHandlerInfo != null)
            {
                var delegateType = TypeCacheUtils.GetType(eventHandlerInfo.DelegateType);
                result = PromiseUtils.FromContinuationInfo(delegateType, eventHandlerInfo) as Delegate;
            }
            return(result == null ? default(T) : (T)(object)Delegate.CreateDelegate(typeof(T), result.Target, result.Method));
        }
Beispiel #4
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);
        }