事件总线 EventHub

一个 C# 的全局事件总线,用来分发事件,比如可以在 Blazor 里,从服务触发 UI 的弹窗事件

 

/// <summary>
/// 事件总线
/// </summary>
public static class EventHub
{
    static ConcurrentDictionary<EventType, Delegate> _hubs = new ConcurrentDictionary<EventType, Delegate>();
    /// <summary>
    /// 添加监听事件
    /// </summary>
    /// <param name="eventType"></param>
    /// <param name="delegate"></param>
    public static void on(EventType @eventType, Delegate @delegate)
    {
        _hubs.AddOrUpdate(@eventType, @delegate, (k, v) => Delegate.Combine(v, @delegate));
    }
    /// <summary>
    /// 移除监听事件
    /// </summary>
    /// <param name="eventType"></param>
    /// <param name="delegate"></param>
    public static void off(EventType @eventType, Delegate @delegate)
    {
        // 把 Delegate 下,和 @delegate 相同指针的方法全删掉
        nint ptr = @delegate.Method.MethodHandle.GetFunctionPointer();
        _hubs.TryRemove(@eventType, out Delegate? outDelegates);
        if (outDelegates is not null)
        {
            List<Delegate> list = outDelegates.GetInvocationList().ToList();
            var allLst = list.FindAll(item => item.Method.MethodHandle.GetFunctionPointer() != ptr);
            foreach (var d in allLst)
            {
                on(@eventType, d);
            }
        }
    }
    public static void emit(EventType @eventType)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            if (d.Target is null) continue;
            (d as Action)?.Invoke();
        }
    }
    public static void emit<T>(EventType @eventType, T arg1)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            if (d.Target is null) continue;
            (d as Action<T>)?.Invoke(arg1);
        }
    }
    public static void emit<T1, T2>(EventType @eventType, T1 arg1, T2 arg2)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            if (d.Target is null) continue;
            (d as Action<T1, T2>)?.Invoke(arg1, arg2);
        }
    }
    public static void emit<T1, T2, T3>(EventType @eventType, T1 arg1, T2 arg2, T3 arg3)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            if (d.Target is null) continue;
            (d as Action<T1, T2, T3>)?.Invoke(arg1, arg2, arg3);
        }
    }
    public static void emit<T1, T2, T3, T4>(EventType @eventType, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            if (d.Target is null) continue;
            (d as Action<T1, T2, T3, T4>)?.Invoke(arg1, arg2, arg3, arg4);
        }
    }
    public static void emit<T1, T2, T3, T4, T5>(EventType @eventType, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            if (d.Target is null) continue;
            (d as Action<T1, T2, T3, T4, T5>)?.Invoke(arg1, arg2, arg3, arg4, arg5);
        }
    }
    public static void emit<T1, T2, T3, T4, T5, T6>(EventType @eventType, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            if (d.Target is null) continue;
            (d as Action<T1, T2, T3, T4, T5, T6>)?.Invoke(arg1, arg2, arg3, arg4, arg5, arg6);
        }
    }
    public static void emit<T1, T2, T3, T4, T5, T6, T7>(EventType @eventType, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
    {
        Delegate[]? delegates = getMethods(@eventType);
        if (delegates is null) return;
        foreach (var d in delegates)
        {
            if (d.Target is null) continue;
            (d as Action<T1, T2, T3, T4, T5, T6, T7>)?.Invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
        }
    }
    static Delegate[]? getMethods(EventType @eventType)
    {
        _hubs.TryGetValue(@eventType, out Delegate? outDelegates);
        return outDelegates?.GetInvocationList();
    }
}
public enum EventType
{
    /// <summary>
    /// 控制台日志
    /// </summary>
    ConsoleLog,
    /// <summary>
    /// 展示消息
    /// </summary>
    ShowInfo,
    /// <summary>
    /// 展示警告
    /// </summary>
    ShowWarring,
    /// <summary>
    /// 展示错误
    /// </summary>
    ShowError,
}

 

使用方法如下:

1,设置监听事件

 

2,使用调用监听,服务的 emit 可以触发 UI 的弹窗;

 

当然 EventHub 还可以用在别处

 

posted @ 2023-09-27 16:06  cchong005  阅读(51)  评论(0编辑  收藏  举报