/// <summary>
        /// Will register a subscriber. Event will be recognized by "eventId" and will be attached to
        /// obj
        /// </summary>
        /// <param name="eventId"></param>
        /// <param name="obj"></param>
        /// <param name="handler"></param>
        public void Subscribe(string eventId, IStateObject obj, Delegate handler, out string eventSubscriptionId, bool isDynamic = false)
        {
            var result = String.Empty;

            if (handler != null)
            {
                //get/created subscribed promises info
                eventId = eventId.ToUpper();
                var handlerSubscriptionId = UniqueIDGenerator.GetEventRelativeUniqueID(obj, eventId);
                LazyBehaviours.AddDependent(obj, UniqueIDGenerator.EVENTPrefix + eventId);
                var promisesInfo = PromisesInfo.CreateInstance(handlerSubscriptionId);

                ////subscribe handler
                var eventMethodName = handler.Method.Name.ToUpper() + eventId;
                eventSubscriptionId = UniqueIDGenerator.GetEventRelativeUniqueID(obj, eventMethodName);
                LazyBehaviours.AddDependent(obj, UniqueIDGenerator.EVENTPrefix + eventMethodName);
                promisesInfo.Add(eventMethodName);
                if (isDynamic)
                {
                    EventPromiseInfoForClient.CreateEventInstance(_stateManager, handler, obj, eventSubscriptionId, actionID: eventId);
                }
                else
                {
                    EventPromiseInfo.CreateEventInstance(_stateManager, handler, obj, eventSubscriptionId);
                }
#if DEBUG
                Debug.Assert(_stateManager.GetObject(eventSubscriptionId) != null, "Event Subscription Failed", "Event for {0} on Object {1} failed", eventId, obj.UniqueID);
#endif
                result = eventSubscriptionId;
            }
            eventSubscriptionId = result;
        }
Пример #2
0
        /// <summary>
        /// Creates a reference table to an Object.
        /// </summary>
        /// <param name="valueObject"></param>
        /// <returns></returns>
        private ReferencesTable CreateObjectReferencesTable(IStateObject valueObject)
        {
            var new_relativeUid = UniqueIDGenerator.GetReferenceTableRelativeUniqueID(valueObject.UniqueID);

            LazyBehaviours.AddDependent(valueObject, UniqueIDGenerator.REFTABLEPrefix);
            ReferencesTable referencesTable = new ReferencesTable();

            referencesTable.UniqueID = new_relativeUid;
            referencesTable.IsReferencedObjectAnIDisposableDependencyControl = valueObject is IDisposableDependencyControl;

            if (StateManager.AllBranchesAttached(valueObject))
            {
                //at this point we have a new pointer with an attached parent
                //which means that it was born on the temp stateManager
                //we cannot just do a switchunique ids because switching
                //is only on the stateManager level
                //we need to promote it from temp to StateManager
                //to make sure that it will be persisted
                _stateManager.AddNewAttachedObject(referencesTable);
            }
            else
            {
                //at this point we have a new pointer with an UNATTACHED parent
                //which means both the parent and the pointer are on the temp stateManager
                //we need to switchunique ids because
                //they are at the stateManager level
                //if the parent is promoted so will be the pointer
                _stateManager.AddNewTemporaryObject(referencesTable);
            }
            return(referencesTable);
        }
Пример #3
0
 private static void ProcessStaticAdoption(IStateObject parent, IStateObject orphan)
 {
     //if (child is still orphan)
     if (!StateManager.AllBranchesAttached(orphan))
     {
         //Get relative id for orphan
         var orphanID    = StateManager.Current.UniqueIDGenerator.GetOrphanUniqueID();
         var newUniqueID = UniqueIDGenerator.GetRelativeUniqueID(parent, orphanID);
         LazyBehaviours.AddDependent(parent, orphanID);
         StateManager.Current.SwitchOrPromoteObject(orphan, newUniqueID, inAdoption: true);
     }
 }
Пример #4
0
 private bool ProcessAdoption(IStateObject parent, IStateObject orphan)
 {
     if (!_promotedOrphans.Contains(orphan))
     {
         //Get relative id for orphan
         var orphanID    = _uniqueIdGenerator.GetOrphanUniqueID();
         var newUniqueID = UniqueIDGenerator.GetRelativeUniqueID(parent, orphanID);
         _stateManager.PromoteObject(orphan, newUniqueID, inAdoption: true);
         LazyBehaviours.AddDependent(parent, orphanID);
         _promotedOrphans.Add(orphan);
         return(true);
     }
     return(false);
 }
Пример #5
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);
        }