< Summary

Information
Class: Trailblazer.Support.LifecycleHookHandler
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Support/LifecycleHooks/LifecycleHookHandler.cs
Line coverage
93%
Covered lines: 28
Uncovered lines: 2
Coverable lines: 30
Total lines: 92
Line coverage: 93.3%
Branch coverage
80%
Covered branches: 8
Total branches: 10
Branch coverage: 80%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
RegisterHook(...)66.66%6681.81%
UnregisterHook(...)100%11100%
InvokeHooks(...)100%22100%
CompareHook()100%22100%

File(s)

/home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Support/LifecycleHooks/LifecycleHookHandler.cs

#LineLine coverage
 1using SwiftCollections;
 2using System;
 3using System.Collections.Generic;
 4
 5namespace Trailblazer.Support;
 6
 7/// <summary>
 8/// Provides functionality to register, unregister, and invoke lifecycle hooks in a thread-safe manner.
 9/// </summary>
 10public class LifecycleHookHandler
 11{
 96112    private readonly object _lifecycleHookLock = new();
 13
 14    /// <summary>
 15    /// Registers a lifecycle hook with the specified owner, order, and callback.
 16    /// Hooks are executed in order of their specified order, and if orders are equal, they are sorted by owner name.
 17    /// The returned IDisposable can be used to unregister the hook when it is no longer needed.
 18    /// </summary>
 19    /// <param name="hooks">The list of hooks to register the new hook with.</param>
 20    /// <param name="owner">The owner of the hook, used to identify and manage the hook.</param>
 21    /// <param name="order">The order in which the hook should be executed relative to other hooks.</param>
 22    /// <param name="callback">The callback to invoke when the hook is executed.</param>
 23    /// <returns>An IDisposable that can be used to unregister the hook.</returns>
 24    /// <exception cref="ArgumentException">Thrown if the owner is null or whitespace.</exception>
 25    /// <exception cref="InvalidOperationException">Thrown if a hook with the same owner is already registered.</excepti
 26    public IDisposable RegisterHook(
 27        SwiftList<OrderedLifecycleHook> hooks,
 28        string owner,
 29        int order,
 30        Action callback)
 31    {
 1232        if (string.IsNullOrWhiteSpace(owner))
 033            throw new ArgumentException("Lifecycle hook owner cannot be null or whitespace.", nameof(owner));
 34
 1235        SwiftThrowHelper.ThrowIfNull(callback, nameof(callback));
 36
 1237        lock (_lifecycleHookLock)
 38        {
 2839            for (int i = 0; i < hooks.Count; i++)
 40            {
 241                if (hooks[i].Owner == owner)
 042                    throw new InvalidOperationException($"Lifecycle hook '{owner}' is already registered.");
 43            }
 44
 1245            hooks.Add(new OrderedLifecycleHook(owner, order, callback));
 1246            hooks.Sort(CompareHook());
 1247        }
 48
 1249        return new LifecycleHookRegistration(() => UnregisterHook(hooks, owner));
 50    }
 51
 52    /// <summary>
 53    /// Unregisters a lifecycle hook based on the specified owner.
 54    /// </summary>
 55    /// <param name="hooks">The list of hooks to unregister the hook from.</param>
 56    /// <param name="owner">The owner of the hook to unregister.</param>
 57    public void UnregisterHook(SwiftList<OrderedLifecycleHook> hooks, string owner)
 58    {
 1259        lock (_lifecycleHookLock)
 60        {
 1261            hooks.RemoveAll(hook => hook.Owner == owner);
 1262        }
 1263    }
 64
 65    /// <summary>
 66    /// Invokes all registered lifecycle hooks in the order they were registered.
 67    /// </summary>
 68    /// <param name="hooks">The list of hooks to invoke.</param>
 69    public void InvokeHooks(SwiftList<OrderedLifecycleHook> hooks)
 70    {
 71        OrderedLifecycleHook[] snapshot;
 772        lock (_lifecycleHookLock)
 73        {
 774            snapshot = hooks.ToArray();
 775        }
 76
 3277        for (int i = 0; i < snapshot.Length; i++)
 978            snapshot[i].Callback();
 779    }
 80
 81    private static Comparer<OrderedLifecycleHook> CompareHook()
 82    {
 1283        return Comparer<OrderedLifecycleHook>.Create((left, right) =>
 1284        {
 1285            int orderCompare = left.Order.CompareTo(right.Order);
 1286            if (orderCompare != 0)
 1287                return orderCompare;
 1288
 1289            return StringComparer.Ordinal.Compare(left.Owner, right.Owner);
 1290        });
 91    }
 92}