Article directory
foreword
I want to make a simple message publishing and subscribing function, but I find that there seems to be no ready-made tools. Either it is Mqtt, which is a message subscription and publication. But I just want to subscribe and publish messages inside the program to decouple the program. There's no way, you can only go up by yourself
Simulate message subscription publishing
MessageHelper in Utils
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NetCore.Utils
{
public class MessageHelper
{
public static List<Message> Messages = new List<Message>();
/// <summary>
/// 消息订阅
/// </summary>
public static void Subscribe(string topic, string key, Action<object> action)
{
var model = Messages.Where(item => item.Topic == topic && item.Key == key).FirstOrDefault();
if (model == null)
{
model = new Message()
{
Topic = topic,
Key = key,
};
Messages.Add(model);
model.Actions.Add(action);
}
else if(model.Actions.Find(item => item.Equals(action)) == null)
{
model.Actions.Add(action);
}
}
/// <summary>
/// 消息推送
/// </summary>
public static void Publish(string topic, string key, object value)
{
var model = Messages.Where(item => item.Topic == topic && item.Key == key).FirstOrDefault();
if (model != null)
{
model.Actions.ForEach(item =>
{
item(value);
});
}
}
}
public class Message
{
public string Topic {
get; set; }
public string Key {
get; set; }
public List<Action<object>> Actions {
get; set; } = new List<Action<object>>();
}
}
use
static void Main(string[] args)
{
MessageHelper.Subscribe("Topic1", "key1", (res) =>
{
var _res = ((string Name, int Age))res;
Console.WriteLine(_res.ToString());
Console.WriteLine("我被调用了1");
});
MessageHelper.Subscribe("Topic2", "key1", (res) =>
{
Console.WriteLine("我被调用了2");
});
MessageHelper.Subscribe("Topic3", "key1", (res) =>
{
Console.WriteLine("我被调用了3");
});
MessageHelper.Subscribe("Topic4", "key1", (res) =>
{
Console.WriteLine("我被调用了4");
});
MessageHelper.Publish("Topic1","key1",(Name:"嘟嘟",Sex:"12"));
Console.ReadLine();
}
Precautions
Here I use the ancestor to pass the value of the temporary variable. How to use Yuanzu, please see my other article. Yuanzu is especially useful for temporary variables
The ancestor of C#, the best temporary variable.
In order to prevent repeated injection, I added judgment code.
Update August 11, 2023, add generics, simplify Topic
public class MessageHelper
{
public static List<Message> Messages = new List<Message>();
/// <summary>
/// 消息订阅
/// </summary>
public static void Subscribe<T_class>( string key, Action<object> action)where T_class : class
{
string topic = typeof(T_class).FullName;
var model = Messages.Where(item => item.Topic == topic && item.Key == key).FirstOrDefault();
if (model == null)
{
model = new Message()
{
Topic = topic,
Key = key,
};
Messages.Add(model);
model.Actions.Add(action);
}
else if (model.Actions.Find(item => item.Equals(action)) == null)
{
model.Actions.Add(action);
}
}
/// <summary>
/// 消息推送
/// </summary>
public static void Publish<T_class>( string key, object value) where T_class : class
{
string topic = typeof(T_class).FullName;
var model = Messages.Where(item => item.Topic == topic && item.Key == key).FirstOrDefault();
if (model != null)
{
model.Actions.ForEach(item =>
{
item(value);
});
}
}
}
public class Message
{
public string Topic {
get; set; }
public string Key {
get; set; }
public List<Action<object>> Actions {
get; set; } = new List<Action<object>>();
}
public static void TestBtn(object value)
{
Console.WriteLine((string)value);
}
static void Main(string[] args)
{
MessageHelper.Subscribe<Program>("Test", TestBtn);
MessageHelper.Subscribe<Program>("Test", TestBtn);
MessageHelper.Subscribe<Program>("Test", TestBtn);
//订阅我做了去重处理
MessageHelper.Publish<Program>("Test","测试文本");
Console.ReadLine();
}