/// <summary> /// Registers your control as a lifetime user of RefreshBus without you having to implement ILifetimeSubscriber. The implementation instead is the following: /// 1. If the RefreshBus sees a refresh for any object that was not Published by yourself /// 1.1 Refreshbus will check your originalObject still Exists /// 1.2 If not then your ParentForm will be .Closed /// 2. If the RefreshBus sees a refresh for your object specifically (that was not published by yourself) /// 2.1 SetDatabaseObject will be called with the new state (in memory as it was passed to Publish) of the object /// /// <para>Note: you can subscribe to EstablishSelfDestructProtocol in your SetDatabaseObject method if you want without worrying about repeat subscriptions but know that only /// the first subscription is respected therefore you should NOT change the database object to a different one</para> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="user"></param> /// <param name="activator"></param> /// <param name="originalObject"></param> public void EstablishSelfDestructProtocol <T>(RDMPSingleDatabaseObjectControl <T> user, IActivateItems activator, T originalObject) where T : DatabaseEntity { //they already subscribed to self destruct protocols - repeat subscriptions can be caused by registering in SetDatabaseObject and then refresh callbacks triggering more calls to SetDatabaseObject within the Controls lifetime var existingSubscription = _selfDestructors.OfType <SelfDestructProtocol <T> >().SingleOrDefault(s => s.User == user); //they have subscribed for this before if (existingSubscription != null) { if (!existingSubscription.OriginalObject.Equals(originalObject))//wait a minute! they subscribed for a different object! { throw new ArgumentException( "user " + user + " attempted to subscribe twice for self destruct but with two different objects '" + existingSubscription.OriginalObject + "' and '" + originalObject + "'", "user"); } else { return;//they subscribed for the same object it's all ok } } //The anonymous refresh callback that updates the user when the object changes or deletes var subscriber = new SelfDestructProtocol <T>(user, activator, originalObject); //keep track of the self destructors independently of the subscription list _selfDestructors.Add(subscriber); //subscribe them now Subscribe(subscriber); var parentForm = user.ParentForm; if (parentForm == null) { throw new ArgumentException("Control must have an established ParentForm, you should not attempt to establish a lifetime subscription until your control is loaded (i.e. don't call this in your constructor)", "c"); } //when their parent closes we unsubscribe them parentForm.FormClosed += (s, e) => { Unsubscribe(subscriber); var toRemove = _selfDestructors.OfType <SelfDestructProtocol <T> >().Single(u => u.User == user); _selfDestructors.Remove(toRemove); }; }
public SelfDestructProtocol(RDMPSingleDatabaseObjectControl <T> user, IActivateItems activator, T originalObject) { _activator = activator; User = user; OriginalObject = originalObject; }