< Summary

Information
Class: MyNet.Primitives.Events.WeakEventSource<T>
Assembly: MyNet.Primitives
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Primitives/Events/WeakEventSource.cs
Tag: 323_28699572109
Line coverage
100%
Covered lines: 21
Uncovered lines: 0
Coverable lines: 21
Total lines: 100
Line coverage: 100%
Branch coverage
85%
Covered branches: 12
Total branches: 14
Branch coverage: 85.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
Subscribe(...)100%11100%
Unsubscribe(...)100%11100%
Raise(...)100%44100%
.ctor(...)100%22100%
TryInvoke(...)100%44100%
Matches(...)50%44100%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Primitives/Events/WeakEventSource.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="WeakEventSource.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Collections.Generic;
 9using System.Reflection;
 10
 11namespace MyNet.Primitives.Events;
 12
 13/// <summary>
 14/// Provides a weak event source implementation that allows subscribers to be garbage collected if they are no longer re
 15/// </summary>
 16/// <typeparam name="TEventArgs">The type of event arguments.</typeparam>
 17public sealed class WeakEventSource<TEventArgs>
 18    where TEventArgs : EventArgs
 19{
 1220    private readonly List<WeakSubscription> _subscriptions = [];
 21
 22    /// <summary>
 23    /// Subscribes to the event with a weak reference to the handler, allowing the subscriber to be garbage collected if
 24    /// </summary>
 25    /// <param name="handler">The event handler to subscribe.</param>
 1226    public void Subscribe(EventHandler<TEventArgs> handler) => _subscriptions.Add(new(handler));
 27
 28    /// <summary>
 29    /// Unsubscribes from the event.
 30    /// </summary>
 31    /// <param name="handler">The event handler to unsubscribe.</param>
 332    public void Unsubscribe(EventHandler<TEventArgs> handler) => _subscriptions.RemoveAll(x => x.Matches(handler));
 33
 34    /// <summary>
 35    /// Raises the event, invoking all subscribed handlers.
 36    /// </summary>
 37    /// <param name="sender">The source of the event.</param>
 38    /// <param name="args">The event arguments.</param>
 39    public void Raise(object sender, TEventArgs args)
 40    {
 4241        for (var i = _subscriptions.Count - 1; i >= 0; i--)
 42        {
 943            if (!_subscriptions[i].TryInvoke(sender, args))
 344                _subscriptions.RemoveAt(i);
 45        }
 1246    }
 47
 48    /// <summary>
 49    /// Represents a weak subscription to an event handler, holding a weak reference to the target object and the method
 50    /// </summary>
 51    private sealed class WeakSubscription
 52    {
 53        private readonly WeakReference? _targetReference;
 54        private readonly MethodInfo _method;
 55
 56        /// <summary>
 57        /// Initializes a new instance of the <see cref="WeakSubscription"/> class with the specified event handler, sto
 58        /// </summary>
 59        /// <param name="handler">The event handler to subscribe.</param>
 60        public WeakSubscription(EventHandler<TEventArgs> handler)
 61        {
 1262            _method = handler.Method;
 63
 1264            if (handler.Target != null)
 965                _targetReference = new(handler.Target);
 1266        }
 67
 68        /// <summary>
 69        /// Attempts to invoke the event handler with the specified sender and event arguments. If the target object has
 70        /// </summary>
 71        /// <param name="sender">The source of the event.</param>
 72        /// <param name="args">The event arguments.</param>
 73        /// <returns>True if the event handler was invoked; otherwise, false.</returns>
 74        public bool TryInvoke(object sender, TEventArgs args)
 75        {
 976            if (_targetReference == null)
 77            {
 378                _method.Invoke(null, [sender, args]);
 379                return true;
 80            }
 81
 682            var target = _targetReference.Target;
 683            if (target == null)
 384                return false;
 85
 386            _method.Invoke(target, [sender, args]);
 387            return true;
 88        }
 89
 90        /// <summary>
 91        /// Determines whether the specified event handler matches the method and target of this weak subscription. This
 92        /// </summary>
 93        /// <param name="handler">The event handler to compare with this weak subscription.</param>
 94        /// <returns>True if the specified event handler matches the method and target of this weak subscription; otherw
 95        public bool Matches(EventHandler<TEventArgs> handler) =>
 396            _method == handler.Method &&
 397            _targetReference?.Target == handler.Target;
 98    }
 99}
 100