Laden...

Wie kann ich zwei unabhängige Applikationen mit Messaging miteinander kommunizieren lassen?

Erstellt von Caveman vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.118 Views
Caveman Themenstarter:in
187 Beiträge seit 2009
vor 4 Jahren
Wie kann ich zwei unabhängige Applikationen mit Messaging miteinander kommunizieren lassen?

Hallo,
ich will mich endlich mal mit dem Thema Events auseinandersetzen.
Dafür habe ich mir eine Konsolenanwendung mit zwei Klassenbibliotheken als Testprojekt angelegt.
Die zwei Klassenbibliotheken (Sender und Receiver) kennen sich nicht gegenseitig, sollen aber miteinander kommunizieren. Mein Ansatz ist nun, dass ich beiden Modulen ein Dictionary<string, delegate> injiziere und darüber die Kommunikation laufen lasse.
Ich weiß nicht, ob der Ansatz überhaupt funktioniert, denn was ich auch probiere, der Delegat in dem Dictionary ist immer null.

Mein derzeitiger Stand auf der Sender-Seite sieht so aus;

    public class Sender
    {
        private Dictionary<string, Delegate> catalog;

        public event EventHandler OnUpdate;

        public Sender(Dictionary<string, Delegate> eventCatalog)
        {
            catalog = eventCatalog;
        }

        public void Init()
        {
            catalog.Add("OnUpdate", OnUpdate);
        }

        public void Raise()
        {
            OnUpdate?.Invoke(this, EventArgs.Empty);
        }
    }
16.806 Beiträge seit 2008
vor 4 Jahren

Caveman, was ist das Ziel?
Meinst Du mit Event wirklich ein .NET Event oder meinst Du "Event" im Sinne von Event Sourcing und Message Handling?
Für mich liest sich das wie letzteres.

Ist das eine Übung, dass Du das Prinzip verstehst?
Wenn ich Event Sourcing mit C# Schulung halte, dann lass ich bewusst C# event Typen weg - das verwirrt viele.
Ich empfehle MediatR oder Reactive Extensions um das Prinzip zu verstehen.

Caveman Themenstarter:in
187 Beiträge seit 2009
vor 4 Jahren

Ja, es geht nur um Übung und Zeitvertreib (wegen Covid19 😃)
Ich habe das jetzt prinzipiell ans Laufen bekommen.

    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, Core.ISampleEvent> eventCatalog = new Dictionary<string, Core.ISampleEvent>();
            Sender sender = new Sender(eventCatalog);
            Receiver receiver = new Receiver(eventCatalog);

            sender.Raise();
            Console.ReadKey();
        }
    }

    public class Sender
    {
        private Dictionary<string, Core.ISampleEvent> catalog;

        public Sender(Dictionary<string, Core.ISampleEvent> eventCatalog)
        {
            catalog = eventCatalog;
            catalog.Add("OnUpdate", new Core.SampleEvent());
        }

         public void Raise()
        {
            catalog["OnUpdate"].Raise();
        }
    }

    public class Receiver
    {
        private Dictionary<string, Core.ISampleEvent> catalog;

        public Receiver(Dictionary<string, Core.ISampleEvent> eventCatalog)
        {
            catalog = eventCatalog;
            catalog["OnUpdate"].OnUpdateEvent += Receiver_OnUpdateEvent;
        }

        private void Receiver_OnUpdateEvent(object sender, EventArgs e)
        {
            Console.WriteLine("Message received");
        }
    }

    public interface ISampleEvent
    {
        event SampleEvent.SampleEventHandler OnUpdateEvent;

        void Raise();
    }

    public class SampleEvent : ISampleEvent
    {
        public delegate void SampleEventHandler(object sender, EventArgs e);

        public event SampleEventHandler OnUpdateEvent;

        public SampleEvent()
        {
        }

        public void Raise()
        {
            OnUpdateEvent?.Invoke(this, EventArgs.Empty);
        }
    }

Eigentlich wäre mein Ziel gewesen, dass ich keine Eventklasse erstellen muss, sondern dieses einfach in ds Dictionary packen kann. Das geht aber offensichtlich nicht!

16.806 Beiträge seit 2008
vor 4 Jahren

Okay, also gehts wirklich um Event im Sinne von Messaging und nicht im die C# event Typen.

Bist auf dem richtigen Weg.
Statt mit Delegates zu arbeiten, würde ich jedoch Action<T> und Func<T> verwenden.
Dann biste nicht vom event-krams aus C# abhängig.

Grundlegend solltest Du aber beachten, dass es im Event Sourcing prinzipiell zwei grundlegende Arten von Events gibt:

  • Commands (jeder Event hat einen Handler, kann Rückgaben haben, laufen seriell)
  • Notifications (ein Event hat viele Handler, keine Rückgaben, laufen parallel)
    (Gibt auch andere Bezeichner; verwende nun die Bezeichner aus den gängigen .NET Bibliotheken)

In der Form ist es in MediatR auch direkt mit Commands und Notifications Implementiert.
Was Du hier implementiert hast sind in diesem Sinne Notifications:

  • Die Events haben viele Handler, aber keine Rückgaben; laufen aber seriell

Willst Du eine Klasse-zu-Klasse Kommunikation, dann ist jedoch ohnehin Reactive Extensions besser geeignet als zB MediatR.
In Reactive Extensions nennt sich das, was Du da hast, Subscriptions.
Understanding Rx: Making the interfaces, subscribing and other Subject<T>s finally click
101 Rx Samples in C#
Da kannste Dir vielleicht noch was am Prinzip abschauen (und es eventuell auch einfacher verstehen).

Caveman Themenstarter:in
187 Beiträge seit 2009
vor 4 Jahren

Danke für die Infos! Ich werde mich mit Reactive Extensions am Wochenende auseinandersetzen!