示例#1
0
        /// <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);
            };
        }
示例#2
0
 public SelfDestructProtocol(RDMPSingleDatabaseObjectControl <T> user, IActivateItems activator, T originalObject)
 {
     _activator     = activator;
     User           = user;
     OriginalObject = originalObject;
 }