diff --git a/Services/SharedEventService/SharedEventService.cs b/Services/SharedEventService/SharedEventService.cs
new file mode 100644
index 0000000..728cf5e
--- /dev/null
+++ b/Services/SharedEventService/SharedEventService.cs
@@ -0,0 +1,48 @@
+using System.Threading.Channels;
+
+namespace RegexBot.Services.SharedEventService;
+///
+/// Implements a queue which any service or module may send objects into,
+/// which are then sent to subscribing services and/or modules. Allows for simple,
+/// basic sharing of information between separate parts of the program.
+///
+class SharedEventService : Service {
+ private readonly Channel _items;
+ //private readonly Task _itemPropagationWorker;
+
+ internal SharedEventService(RegexbotClient bot) : base(bot) {
+ _items = Channel.CreateUnbounded();
+ _ = Task.Factory.StartNew(ItemPropagator, CancellationToken.None,
+ TaskCreationOptions.LongRunning, TaskScheduler.Default);
+ }
+
+ // Hooked (lock this on self)
+ internal event RegexbotClient.IncomingSharedEventHandler? Subscribers;
+
+ internal async Task PushSharedEventAsync(ISharedEvent ev) {
+ await _items.Writer.WriteAsync(ev);
+ }
+
+ private async Task ItemPropagator() {
+ while (true) {
+ var ev = await _items.Reader.ReadAsync();
+
+ Delegate[]? subscribed;
+ lock (this) {
+ subscribed = Subscribers?.GetInvocationList();
+ if (subscribed == null || subscribed.Length == 0) return;
+ }
+
+ foreach (var handler in subscribed) {
+ // Fire and forget!
+ _ = Task.Run(async () => {
+ try {
+ await (Task)handler.DynamicInvoke(ev)!;
+ } catch (Exception ex) {
+ Log("Unhandled exception in shared event handler:" + ex.ToString());
+ }
+ });
+ }
+ }
+ }
+}