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