SoFunction
Updated on 2025-03-07

Example of C# Message-based Publishing Subscription Model (Part 2)

A background

existAbove articleIn this article, we introduce a model that is completely based on message publishing and subscription. In this article, I will introduce a simple message-based publishing and subscription model. In this model, we will encapsulate specific events and event subscriptions by building a Publisher class. This is a lighter-weight method. The main purpose of using this is to reduce the degree of coupling between classes, so as to facilitate the expansion and access of code, and ultimately make the code structure more reasonable.

Let’s first look at the specific composition of the Publisher class. We will give a detailed explanation and analysis of this class later.

using System;
using ;
using ;
using ;
 
namespace 
{
    /// <summary>
    /// Publisher/Subscriber pattern
    /// This infrastructure works as an instance.
    /// </summary>
    public sealed class Publisher<EventType> where EventType : IComparable
    {
        private static readonly object _locker = new object();
 
        private static readonly Dictionary<EventType, List<Action<object, object, object, object>>> _eventTypeList = new Dictionary<EventType, List<Action<object, object, object, object>>>();
 
        public static void Attach(EventType key, Action<object, object, object, object> act)
        {
            lock (_locker)
            {
                if (!_eventTypeList.ContainsKey(key))
                    _eventTypeList.Add(key, new List<Action<object, object, object, object>>());
                if (!_eventTypeList[key].Contains(act))
                    _eventTypeList[key].Add(act);
            }
        }
 
        public static void Detach(EventType key)
        {
            lock (_locker)
            {
                if (_eventTypeList.ContainsKey(key))
                {
                    _eventTypeList[key].Clear();
                }
            }
        }
 
        public static void Detach(EventType key, Action<object, object, object, object> act)
        {
            lock (_locker)
            {
                if (_eventTypeList.ContainsKey(key) && _eventTypeList[key].Contains(act))
                {
                    _eventTypeList[key].Remove(act);
                }
            }
        }
 
        public static void Notify(EventType key, object p1, object p2, object p3, object p4)
        {
            lock (_locker)
            {
                if (_eventTypeList.ContainsKey(key))
                {
                    foreach (var act in _eventTypeList[key])
                    {
                        (p1, p2, p3, p4);
                    }
                }
            }
        }
 
        public static void Notify(EventType key, object p1, object p2, object p3)
        {
            Notify(key, p1, p2, p3, null);
        }
 
        public static void Notify(EventType key, object p1, object p2)
        {
            Notify(key, p1, p2, null, null);
        }
 
        public static void Notify(EventType key, object p1)
        {
            Notify(key, p1, null, null, null);
        }
 
        public static void Notify(EventType key)
        {
            Notify(key, null, null, null, null);
        }
    }
}

2. Complete the analysis

In the Publisher class above, we use a generic parameter of EventType type. This parameter is defined by ourselves. It is generally defined as an enum type to identify our unique event type. After defining the generic parameter, we define an _eventTypeList to define the specific EventType and the corresponding processing method and put this into a static Dictionary. Of course, an event in our code can correspond to multiple processing Actions, but in general, an event has only one corresponding processing function. This is not excluded here. In addition, we define four object-type parameters by default to pass parameters to the processing function. In addition, our methods are all static methods and locks are added during the subscription process to ensure the security of threads in a multi-threaded environment.

3. Use process

In the specific use process, three important steps are mainly included: 1. Define the event type. 2  Message receiver subscribes event processing (usually the only subscription at the time when the Attach method is called in the constructor). 3. The event publisher publishes an event (the sender of the event triggers the time and passes parameters, and calls the Notify method to trigger the event). Complete the above three steps to complete the simple processing of the entire message-based publishing subscription. This Publisher class can be successfully implemented in general event processing methods. The most important thing is that the event itself is simple and easy to understand and can minimize the coupling between modules to the greatest extent, so it is still very convenient when used.

The above is the detailed content of the C# publishing subscription model based on message (Part 2). For more information about the C# publishing subscription model, please follow my other related articles!