public void WeakDelegateWorksWithStaticMethodDelegates()
        {
            var action = new DelegateReference(
                (Action)SomeClassHandler.StaticMethod, false);

            Assert.IsNotNull(action.Target);
        }
        public virtual SubscriptionToken Subscribe(Action action, ThreadOption threadOption, bool keepSubscriberReferenceAlive)
        {
            var actionReference = new DelegateReference(action, keepSubscriberReferenceAlive);

            ISubscription subscription;

            switch (threadOption)
            {
            case ThreadOption.PublisherThread:
                subscription = new Subscription(actionReference);
                break;

            case ThreadOption.BackgroundThread:
                subscription = new BackgroundDispatcherSubscription(actionReference);
                break;

            case ThreadOption.UIThread:
                if (m_context == null)
                {
                    throw new InvalidOperationException("To use the UIThread option for subscribing, the EventAggregator must be constructed on the UI thread.");
                }

                subscription = new ContextDispatcherSubscription(actionReference, m_context);
                break;

            default:
                subscription = new Subscription(actionReference);
                break;
            }

            return(Subscribe(subscription));
        }
        /// <summary>
        /// Subscribe to a specific event.
        /// <param name="eventName">Name of the event to subscribe to</param>
        /// <param name="elementId">ElementId of the model element, which specifies when to notify the observer.</param>
        /// <param name="action">Action to call on notification.</param>
        /// </summary>
        public void Subscribe(string eventName, Guid elementId, Action <T> action)
        {
            if (String.IsNullOrEmpty(eventName))
            {
                throw new ArgumentException("eventName");
            }

            IDelegateReference actionReference = new DelegateReference(action, false);
            IDelegateReference filterReference = new DelegateReference(new Predicate <T>(delegate { return(true); }), true);
            IEventSubscription subscription    = new EventSubscription <T>(actionReference, filterReference);

            lock (dictionary)
            {
                if (!dictionary.Keys.Contains(eventName))
                {
                    dictionary.Add(eventName, new Dictionary <Guid, List <IEventSubscription> >());
                }

                if (!dictionary[eventName].Keys.Contains(elementId))
                {
                    dictionary[eventName].Add(elementId, new List <IEventSubscription>());
                }
                dictionary[eventName][elementId].Add(subscription);
            }
        }
Пример #4
0
        /// <summary>
        /// Subscribes a delegate to an event.
        /// </summary>
        /// <param name="action">The delegate that gets executed when the event is published.</param>
        /// <param name="threadOption">Specifies on which thread to receive the delegate callback.</param>
        /// <param name="keepSubscriberReferenceAlive">When <see langword="true"/>, the <see cref="PubSubEvent"/> keeps a reference to the subscriber so it does not get garbage collected.</param>
        /// <returns>A <see cref="SubscriptionToken"/> that uniquely identifies the added subscription.</returns>
        /// <remarks>
        /// If <paramref name="keepSubscriberReferenceAlive"/> is set to <see langword="false" />, <see cref="PubSubEvent"/> will maintain a <see cref="WeakReference"/> to the Target of the supplied <paramref name="action"/> delegate.
        /// If not using a WeakReference (<paramref name="keepSubscriberReferenceAlive"/> is <see langword="true" />), the user must explicitly call Unsubscribe for the event when disposing the subscriber in order to avoid memory leaks or unexpected behavior.
        /// <para/>
        /// The PubSubEvent collection is thread-safe.
        /// </remarks>
        public virtual SubscriptionToken Subscribe(Action action, ThreadOption threadOption, bool keepSubscriberReferenceAlive)
        {
            IDelegateReference actionReference = new DelegateReference(action, keepSubscriberReferenceAlive);

            EventSubscription subscription;

            switch (threadOption)
            {
            case ThreadOption.PublisherThread:
                subscription = new EventSubscription(actionReference);
                break;

            case ThreadOption.BackgroundThread:
                subscription = new BackgroundEventSubscription(actionReference);
                break;

            case ThreadOption.UIThread:
                if (SynchronizationContext == null)
                {
                    throw new InvalidOperationException(Resources.EventAggregatorNotConstructedOnUIThread);
                }
                subscription = new DispatcherEventSubscription(actionReference, SynchronizationContext);
                break;

            default:
                subscription = new EventSubscription(actionReference);
                break;
            }

            return(InternalSubscribe(subscription));
        }
Пример #5
0
        /// <summary>
        /// Subscribe to the event. The observer will be notified, whenever a model element of
        /// the given domain class type (which does include all descendants) is included in the
        /// specific event.
        /// </summary>
        /// <param name="domainClassInfo">DomainClassInfo specifying when to notify the observer.</param>
        /// <param name="action">Action to call on the observer.</param>
        public void Subscribe(DomainClassInfo domainClassInfo, Action <T> action)
        {
            IDelegateReference actionReference = new DelegateReference(action, false);
            IDelegateReference filterReference = new DelegateReference(new Predicate <T>(delegate { return(true); }), true);
            IEventSubscription subscription    = new EventSubscription <T>(actionReference, filterReference);

            lock (dictionary)
            {
                Guid domainClassId = domainClassInfo.Id;

                if (!dictionary.Keys.Contains(domainClassId))
                {
                    dictionary.Add(domainClassId, new List <IEventSubscription>());
                }

                dictionary[domainClassId].Add(subscription);

                // process descendants
                foreach (DomainClassInfo info in domainClassInfo.AllDescendants)
                {
                    domainClassId = info.Id;

                    if (!dictionary.Keys.Contains(domainClassId))
                    {
                        dictionary.Add(domainClassId, new List <IEventSubscription>());
                    }

                    dictionary[domainClassId].Add(subscription);
                }
            }
        }
Пример #6
0
            public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
            {
                var del = (Delegate)obj;

                info.SetType(typeof(DelegateReference));
                info.AddValue("Delegates", DelegateReference.FlattenDelegate(del));
            }
 public void NullDelegateThrows()
 {
     Assert.ThrowsException <ArgumentNullException>(() =>
     {
         var action = new DelegateReference(null, true);
     });
 }
Пример #8
0
        /// <summary>
        /// Subscribes a delegate to an event.
        /// </summary>
        /// <param name="action">The delegate that gets executed when the event is published.</param>
        /// <param name="threadOption">Specifies on which thread to receive the delegate callback.</param>
        /// <param name="keepSubscriberReferenceAlive">When <see langword="true"/>, the <seealso cref="CompositeWpfEvent{TPayload}"/> keeps a reference to the subscriber so it does not get garbage collected.</param>
        /// <param name="filter">Filter to evaluate if the subscriber should receive the event.</param>
        /// <returns>A <see cref="SubscriptionToken"/> that uniquely identifies the added subscription.</returns>
        /// <remarks>
        /// If <paramref name="keepSubscriberReferenceAlive"/> is set to <see langword="false" />, <see cref="CompositeWpfEvent{TPayload}"/> will maintain a <seealso cref="WeakReference"/> to the Target of the supplied <paramref name="action"/> delegate.
        /// If not using a WeakReference (<paramref name="keepSubscriberReferenceAlive"/> is <see langword="true" />), the user must explicitly call Unsubscribe for the event when disposing the subscriber in order to avoid memory leaks or unexepcted behavior.
        ///
        /// The CompositeWpfEvent collection is thread-safe.
        /// </remarks>
        public virtual SubscriptionToken Subscribe(Action <TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive, Predicate <TPayload> filter)
        {
            IDelegateReference           actionReference = new DelegateReference(action, keepSubscriberReferenceAlive);
            IDelegateReference           filterReference = new DelegateReference(filter, keepSubscriberReferenceAlive);
            EventSubscription <TPayload> subscription;

            switch (threadOption)
            {
            case ThreadOption.PublisherThread:
                subscription = new EventSubscription <TPayload>(actionReference, filterReference);
                break;

            case ThreadOption.BackgroundThread:
                subscription = new BackgroundEventSubscription <TPayload>(actionReference, filterReference);
                break;

            case ThreadOption.UIThread:
                subscription = new DispatcherEventSubscription <TPayload>(actionReference, filterReference, UIDispatcher);
                break;

            default:
                subscription = new EventSubscription <TPayload>(actionReference, filterReference);
                break;
            }


            return(base.InternalSubscribe(subscription));
        }
Пример #9
0
        /// <summary>
        /// Subscribes the specified action.
        /// </summary>
        /// <param name="action">The action.</param>
        /// <param name="threadOption">The thread option.</param>
        /// <param name="keepSubscriberReferenceAlive">if set to <c>true</c> [keep subscriber reference alive].</param>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        public override SubscriptionToken Subscribe(Action <TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive, Predicate <TPayload> filter)
        {
            IDelegateReference actionReference = new DelegateReference(action, keepSubscriberReferenceAlive);
            IDelegateReference filterReference = filter != null
                ? new DelegateReference(filter, keepSubscriberReferenceAlive)
                : new DelegateReference(EmptyPredicate, true);

            EventSubscription <TPayload> subscription;

            switch (threadOption)
            {
            case ThreadOption.PublisherThread:
                subscription = new CiEventSubscription <TPayload>(actionReference, filterReference);
                break;

            case ThreadOption.BackgroundThread:
                subscription = new CiBackgroundEventSubscription <TPayload>(actionReference, filterReference);
                break;

            case ThreadOption.UIThread:
                subscription = new CiDispatcherEventSubscription <TPayload>(actionReference, filterReference, SynchronizationContext);
                break;

            default:
                subscription = new CiEventSubscription <TPayload>(actionReference, filterReference);
                break;
            }

            return(InternalSubscribe(subscription));
        }
Пример #10
0
        /// <summary>
        /// Subscribes the given delegate reference to the SelectionChanging event. The delegate will be invoked on the specified thread.
        /// </summary>
        /// <param name="actionReference"></param>
        /// <param name="threadOption"></param>
        /// <returns></returns>
        public SubscriptionToken Subscribe(IDelegateReference actionReference, ThreadOption threadOption)
        {
            IDelegateReference filterReference =
                new DelegateReference(new Predicate <SelectionBase <T> >(_ => true), true);

            EventSubscription <SelectionBase <T> > subscription;

            switch (threadOption)
            {
            case ThreadOption.PublisherThread:
                subscription = new EventSubscription <SelectionBase <T> >(actionReference, filterReference);
                break;

            case ThreadOption.BackgroundThread:
                subscription = new BackgroundEventSubscription <SelectionBase <T> >(actionReference, filterReference);
                break;

            case ThreadOption.UIThread:
                subscription = new DispatcherEventSubscription <SelectionBase <T> >(actionReference, filterReference, UIDispatcher);
                break;

            default:
                throw new NotImplementedException("Thread Option not available.");     // Impossible to happen
            }
            return(base.InternalSubscribe(subscription));
        }
Пример #11
0
        /// <summary>
        /// Subscribes a delegate to an event.
        /// </summary>
        /// <param name="action">The delegate that gets executed when the event is published.</param>
        /// <param name="threadOption">Specifies on which thread to receive the delegate callback.</param>
        /// <param name="keepSubscriberReferenceAlive">When <see langword="true"/>, the <seealso cref="CompositeSynchronizationContextEvent{TPayload}"/> keeps a reference to the subscriber so it does not get garbage collected.</param>
        /// <param name="filter">Filter to evaluate if the subscriber should receive the event.</param>
        /// <returns>A <see cref="SubscriptionToken"/> that uniquely identifies the added subscription.</returns>
        /// <remarks>
        /// If <paramref name="keepSubscriberReferenceAlive"/> is set to <see langword="false" />, <see cref="CompositeSynchronizationContextEvent{TPayload}"/> will maintain a <seealso cref="WeakReference"/> to the Target of the supplied <paramref name="action"/> delegate.
        /// If not using a WeakReference (<paramref name="keepSubscriberReferenceAlive"/> is <see langword="true" />), the user must explicitly call Unsubscribe for the event when disposing the subscriber in order to avoid memory leaks or unexepcted behavior.
        ///
        /// The CompositeSynchronizationContextEvent collection is thread-safe.
        /// </remarks>
        public virtual SubscriptionToken Subscribe(Action <TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive, Predicate <TPayload> filter)
        {
            IDelegateReference           actionReference = new DelegateReference(action, keepSubscriberReferenceAlive);
            IDelegateReference           filterReference = new DelegateReference(filter, keepSubscriberReferenceAlive);
            EventSubscription <TPayload> subscription;

            switch (threadOption)
            {
            case ThreadOption.PublisherThread:
                subscription = new EventSubscription <TPayload>(actionReference, filterReference);
                break;

            case ThreadOption.BackgroundThread:
                subscription = new BackgroundEventSubscription <TPayload>(actionReference, filterReference);
                break;

            case ThreadOption.SubscriberAffinityThread:
                subscription = new CompositeEventSubscription <TPayload>(actionReference, filterReference, SynchronizationContext.Current);
                break;

            default:
                subscription = new EventSubscription <TPayload>(actionReference, filterReference);
                break;
            }


            return(base.InternalSubscribe(subscription));
        }
Пример #12
0
    /// <summary>
    /// Subscribes a delegate to an event.
    /// </summary>
    /// <param name="action">The delegate that gets executed when the event is published.</param>
    /// <param name="keepSubscriberReferenceAlive">When <see langword="true"/>, the <see cref="PubSubEvent"/> keeps a reference to the subscriber so it does not get garbage collected.</param>
    /// <returns>A <see cref="SubscriptionToken"/> that uniquely identifies the added subscription.</returns>
    /// <remarks>
    /// If <paramref name="keepSubscriberReferenceAlive"/> is set to <see langword="false" />, <see cref="PubSubEvent"/> will maintain a <see cref="WeakReference"/> to the Target of the supplied <paramref name="action"/> delegate.
    /// If not using a WeakReference (<paramref name="keepSubscriberReferenceAlive"/> is <see langword="true" />), the user must explicitly call Unsubscribe for the event when disposing the subscriber in order to avoid memory leaks or unexpected behavior.
    /// <para/>
    /// The PubSubEvent collection is thread-safe.
    /// </remarks>
    public virtual SubscriptionToken Subscribe(Action action, bool keepSubscriberReferenceAlive = true)
    {
        IDelegateReference actionReference = new DelegateReference(action, keepSubscriberReferenceAlive);

        EventSubscription subscription = new EventSubscription(actionReference);

        return(InternalSubscribe(subscription));
    }
Пример #13
0
        public void Construct_WeakReferenceStaticDelegate_ShouldSet()
        {
            // Prepare
            var delegateReference = new DelegateReference((Action)ClassFixture.StaticEmptyMethod, false);

            // Assert
            Assert.NotNull(delegateReference.Delegate);
        }
Пример #14
0
        public void TargetEqualsActionShouldReturnTrue()
        {
            var             classHandler = new SomeClassHandler();
            Action <string> myAction     = new Action <string>(classHandler.MyAction);

            var weakAction = new DelegateReference(myAction, false);

            Assert.True(weakAction.TargetEquals(new Action <string>(classHandler.MyAction)));
        }
Пример #15
0
        public void KeepAlivePreventsDelegateFromBeingCollected()
        {
            var delegates         = new SomeClassHandler();
            var delegateReference = new DelegateReference((Action <string>)delegates.DoEvent, true);

            delegates = null;
            GC.Collect();

            Assert.NotNull(delegateReference.Target);
        }
        public void NotKeepAliveAllowsDelegateToBeCollected()
        {
            var delegates = new SomeClassHandler();
            var delegateReference = new DelegateReference((Action<string>)delegates.DoEvent, false);

            delegates = null;
            GC.Collect();

            Assert.IsNull(delegateReference.Target);
        }
Пример #17
0
        public void TargetShouldReturnAction()
        {
            string          something = null;
            Action <string> myAction  = (arg => something = arg);

            var weakAction = new DelegateReference(myAction, false);

            ((Action <string>)weakAction.Target)("payload");
            Assert.AreEqual("payload", something);
        }
        public void TargetShouldReturnAction()
        {
            var classHandler = new SomeClassHandler();
            Action<string> myAction = new Action<string>(classHandler.MyAction);

            var weakAction = new DelegateReference(myAction, false);

            ((Action<string>)weakAction.Target)("payload");
            Assert.AreEqual("payload", classHandler.MyActionArg);
        }
        public void KeepAlivePreventsDelegateFromBeingCollected()
        {
            var delegates = new SomeClassHandler();
            var delegateReference = new DelegateReference((Action<string>)delegates.DoEvent, true);

            delegates = null;
            GC.Collect();

            Assert.IsNotNull(delegateReference.Target);
        }
Пример #20
0
        public void NotKeepAliveAllowsDelegateToBeCollected()
        {
            var delegates         = new SomeClassHandler();
            var delegateReference = new DelegateReference((Action <string>)delegates.DoEvent, false);

            delegates = null;
            GC.Collect();

            Assert.Null(delegateReference.Target);
        }
Пример #21
0
        public void TargetShouldReturnAction()
        {
            var             classHandler = new SomeClassHandler();
            Action <string> myAction     = new Action <string>(classHandler.MyAction);

            var weakAction = new DelegateReference(myAction, false);

            ((Action <string>)weakAction.Target)("payload");
            Assert.Equal("payload", classHandler.MyActionArg);
        }
Пример #22
0
        public void TargetEqualsNullShouldReturnFalseIfTargetAlive()
        {
            SomeClassHandler handler = new SomeClassHandler();
            var weakHandlerRef       = new WeakReference(handler);

            var action = new DelegateReference((Action <string>)handler.DoEvent, false);

            Assert.False(action.TargetEquals(null));
            Assert.True(weakHandlerRef.IsAlive);
            GC.KeepAlive(handler);
        }
Пример #23
0
        public void Not_Keep_Alive_Should_Allow_Delegate_To_Be_Collected()
        {
            var delegates         = new SomeClassHandler();
            var delegateReference = new DelegateReference((Action <string>)delegates.DoEvent, false);

            // ReSharper disable RedundantAssignment
            delegates = null;
            // ReSharper restore RedundantAssignment
            GC.Collect();

            Assert.Null(delegateReference.Target);
        }
Пример #24
0
        public void Keep_Alive_Should_Prevent_Delegate_From_Being_Collected()
        {
            var delegates         = new SomeClassHandler();
            var delegateReference = new DelegateReference((Action <string>)delegates.DoEvent, true);

            // ReSharper disable RedundantAssignment
            delegates = null;
            // ReSharper restore RedundantAssignment
            GC.Collect();

            Assert.NotNull(delegateReference.Target);
        }
Пример #25
0
        public void ShouldReturnNullIfTargetNotAlive()
        {
            SomeClassHandler handler = new SomeClassHandler();
            var weakHandlerRef       = new WeakReference(handler);

            var action = new DelegateReference((Action <string>)handler.DoEvent, false);

            handler = null;
            GC.Collect();
            Assert.False(weakHandlerRef.IsAlive);

            Assert.Null(action.Target);
        }
Пример #26
0
        public void NotKeepAliveKeepsDelegateIfStillAlive()
        {
            var delegates         = new SomeClassHandler();
            var delegateReference = new DelegateReference((Action <string>)delegates.DoEvent, false);

            GC.Collect();

            Assert.IsNotNull(delegateReference.Target);

            delegates = null;
            GC.Collect();

            Assert.IsNull(delegateReference.Target);
        }
Пример #27
0
        public void TargetShouldReturnAction()
        {
            //string something = null;
            //Action<string> myAction = (arg => something = arg);

            SomeClassHandler classHandler = new SomeClassHandler();
            Action <string>  myAction     = new Action <string>(classHandler.MyAction);

            var weakAction = new DelegateReference(myAction, false);

            ((Action <string>)weakAction.Target)("payload");
            //Assert.AreEqual("payload", something);
            Assert.AreEqual("payload", classHandler.Value);
        }
Пример #28
0
        public void Should_Return_Null_If_Target_NotAlive()
        {
            SomeClassHandler handler = new SomeClassHandler();
            var weakHandlerRef       = new WeakReference(handler);

            var action = new DelegateReference((Action <string>)handler.DoEvent, false);

            // ReSharper disable RedundantAssignment
            handler = null;
            // ReSharper restore RedundantAssignment
            GC.Collect();
            Assert.False(weakHandlerRef.IsAlive);
            Assert.Null(action.Target);
        }
Пример #29
0
        public void ShouldAllowCollectionOfOriginalDelegate()
        {
            var classHandler = new SomeClassHandler();
            Action<string> myAction = new Action<string>(classHandler.MyAction);

            var weakAction = new DelegateReference(myAction, false);

            var originalAction = new WeakReference(myAction);
            myAction = null;
            GC.Collect();
            Assert.IsFalse(originalAction.IsAlive);

            ((Action<string>)weakAction.Target)("payload");
            Assert.AreEqual("payload", classHandler.MyActionArg);
        }
        public void ShouldAllowCollectionOfOriginalDelegate()
        {
            var classHandler = new SomeClassHandler();
            Action<string> myAction = new Action<string>(classHandler.MyAction);

            var weakAction = new DelegateReference(myAction, false);

            var originalAction = new WeakReference(myAction);
            myAction = null;
            GC.Collect();
            Assert.IsFalse(originalAction.IsAlive);

            ((Action<string>)weakAction.Target)("payload");
            Assert.AreEqual("payload", classHandler.MyActionArg);
        }
Пример #31
0
        public async Task GetDelegate_DelegateNotAlive_ShouldReturnNull()
        {
            // Prepare
            var classFixture      = new ClassFixture();
            var delegateReference = new DelegateReference((Action)classFixture.EmptyMethod, false);

            // Act
            classFixture = null !;
            await Task.Delay(100);

            GC.Collect();

            // Assert
            Assert.Null(delegateReference.Delegate);
        }
        public void NotKeepAliveKeepsDelegateIfStillAlive()
        {
            var delegates = new SomeClassHandler();
            var delegateReference = new DelegateReference((Action<string>)delegates.DoEvent, false);

            GC.Collect();

            Assert.IsNotNull(delegateReference.Target);

            GC.KeepAlive(delegates);  //Makes delegates ineligible for garbage collection until this point (to prevent oompiler optimizations that may release the referenced object prematurely).
            delegates = null;
            GC.Collect();

            Assert.IsNull(delegateReference.Target);
        }
Пример #33
0
        public async Task Construct_KeepReferenceAliveFalse_ShouldGetGarbageCollected()
        {
            // Prepare
            Action referenceAction   = () => { };
            var    delegateReference = new DelegateReference(referenceAction, false);

            // Act
            referenceAction = null !;
            await Task.Delay(100);

            GC.Collect();

            // Assert
            Assert.NotNull(delegateReference.Delegate);
        }
Пример #34
0
        public void NotKeepAliveKeepsDelegateIfStillAlive()
        {
            var delegates         = new SomeClassHandler();
            var delegateReference = new DelegateReference((Action <string>)delegates.DoEvent, false);

            GC.Collect();

            Assert.NotNull(delegateReference.Target);

            GC.KeepAlive(delegates);  //Makes delegates ineligible for garbage collection until this point (to prevent oompiler optimizations that may release the referenced object prematurely).
            delegates = null;
            GC.Collect();

            Assert.Null(delegateReference.Target);
        }
Пример #35
0
        public void ShouldAllowCollectionOfOriginalDelegate()
        {
            string          something = null;
            Action <string> myAction  = (arg => something = arg);

            var weakAction = new DelegateReference(myAction, false);

            var originalAction = new WeakReference(myAction);

            myAction = null;
            GC.Collect();
            Assert.IsFalse(originalAction.IsAlive);

            ((Action <string>)weakAction.Target)("payload");
            Assert.AreEqual("payload", something);
        }
 public void NullDelegateThrows()
 {
     Assert.ThrowsException<ArgumentNullException>(() =>
     {
         var action = new DelegateReference(null, true);
     });
 }
        public void ShouldReturnNullIfTargetNotAlive()
        {
            SomeClassHandler handler = new SomeClassHandler();
            var weakHandlerRef = new WeakReference(handler);

            var action = new DelegateReference((Action<string>)handler.DoEvent, false);

            handler = null;
            GC.Collect();
            Assert.IsFalse(weakHandlerRef.IsAlive);

            Assert.IsNull(action.Target);
        }
        public void WeakDelegateWorksWithStaticMethodDelegates()
        {
            var action = new DelegateReference((Action)SomeClassHandler.StaticMethod, false);

            Assert.IsNotNull(action.Target);
        }
 public void NullDelegateThrows()
 {
     var action = new DelegateReference(null, true);
 }