C# Zyklische Abhängigkeiten auflösen

tollertyp schrieb:
Ich glaube bei Henne und Ei ging es weniger darum die Natur widerzuspiegeln, es sollte als einfaches Beispiel dienen.
Genau, das war das einfachste Beispiel, welches jeder gut nachvollziehen kann.
 
Ghost_Rider_R schrieb:
Genau, das war das einfachste Beispiel, welches jeder gut nachvollziehen kann.
Also ich finde das Beispiel komplizierter als das GUI-Controller-Beispiel.
Aber wie gesagt. Im Prinzip übergibst Du keinen Zeiger bzw. Referenz aufs ganze Objekt, sondern nur auf die Funktion bzw. Methode. Dann ist nämlich der Objekttyp egal weil Du halt nur einen Typ "Methode" hast den Du einfach aufrufst.
 
@Ghost_Rider_R :

Ein Henne-Ei Problem sehe ich hier nicht. Das wäre eine bidirektionale Komposition Aggregation und funktioniert nicht, weil es bei Erzeugung einer Henne oder eines Eis in einer Endlosschleife mündet.

Dein Problem klingt für mich nach Inter Thread Kommunikation.
Den einfachsten Fall hast du ja schon skizzziert. Dem Workerthread ist der Button bekannt. Dann kann der Thread am Ende den Button aktivieren.

Man kann auch eine gemeinsam genutzte Ressource definieren, die beiden bekannt ist. Am Ende schreibt der Thread das Ergebnis da rein. Schreibt man während der Berechnung mehrmals eine Zahl in die Ressource kann auf dieser Basis auch eine Fortschrittsanzeige implementiert :)
 
Hier mal ein Beispiel wie man es lösen kann, je nachdem was der Controller für Schnittstellen anbietet. Den Button habe ich simuliert, genauso wie das Warten, dass der Benutzer wieder auf den Button drücken kann.

dotnetfiddle
 
Ghost_Rider_R schrieb:
Vielleicht kann das ja jemand lösen:

Public Class Henne
...

C#:
public class Henne
{
    private readonly Lazy<Ei> ei;

    public Henne(Lazy<Ei> ei)
    {
        this.ei = ei;
    }
}

public class Ei
{
    private readonly Lazy<Henne> henne;

    public Ei(Lazy<Henne> henne)
    {
        this.henne = henne;
    }
}

Und registriert mit:

C#:
services.AddTransient<Henne>();
services.AddTransient<Ei>();
services.AddTransient(provider => new Lazy<Henne>(provider.GetService<Henne>));
services.AddTransient(provider => new Lazy<Ei>(provider.GetService<Ei>));

Aber nur weil es geht, bedeutet das nicht, dass es gute Architektur ist.
 
Zuletzt bearbeitet:
Ich sehe das ähnlich. Zyklische Abhänigkeiten solltem an meines Erachtens nach so auflösen, dass sie gänzlich vermieden werden. Ohne ein konkreteres Beispiel kann man dir aber schlecht Verbesserungen vorschlagen.
  • Entweder sind sie zu allgemein (Das Henne-Ei Beispiel zu lösen geht zwar irgendwie, ist aber Quatsch, weil es in der Praxis so nicht vorkommt)
  • Ein "besseres" Design vorzuschlagen ist nicht möglich, weil man den Ursprung deiner Problematik bestenfalls erahnen kann
Ist der echte Code geheim (weil von der Firma) oder zu komplex um ihn zu posten? Falls ja, Beschreibe dein Problem vielleicht noch mal etwas genauer.
 
Und die wichtigste Frage ist halt immer bei solchen Abhängigkeiten: Müssen sich die Sachen wirklich kennen?
Wie gesagt, ein Button muss nicht jeden (niemanden) kennen, der auf seine Events reagiert... Aber jemand, der will, dass auf einen Button reagiert wird, der muss den Button kennen (muss nicht der Controller sein, sondern eben der "Glue-Code" dazwischen - der Glue-Code kennt wiederrum beide).
 
  • Gefällt mir
Reaktionen: Ghost_Rider_R
Tatsächlich entspricht mein derzeitiges Projekt dem ursprünglichen Beispiel / Vorschlag von @tollertyp.
Anbei ein Auszug des Codes:

C#:
        internal SpeedtestClient(ClientGUI clientGUI)
        {
            this.clientGUI = clientGUI;
            clientGUI.ZuweisenSpeedtestClient(this);
        }

        [STAThread]
        public static void Main()
        {
            Application application = new();
            ClientGUI clientGUI = new();
            _ = new SpeedtestClient(clientGUI);
            application.Run(clientGUI);
        }

Vielleicht denke ich hier auch einfach zu kompliziert, im Enddefekt habe ich hier ja ein ganz klassisches MVC-Konzept (noch ohne Model), in dem die View nun mal auf den Controller zugreifen muss und der Controller auf die GUI:

1645785733373.png

Quelle s. Screenshot.

Ist das an der Stelle vielleicht auch einfach so in Ordnung?

Es gibt allerdings auch diese Variante des MVC im Netz:
1645785992156.png

Quelle: https://stackoverflow.com/questions/40900741/mvc-variables-in-model-or-controller

Nur wie kann der User denn direkt mit dem Controller agieren?
Er braucht doch die GUI dazu oder?

LG Ghost
 
Und gerade bei GUI danke ich braucht es diese Art eben nicht. Aber um das genau zu beurteilen, müsste man mehr vom Code sehen.

Weil ich behaupte: Deine GUI muss niemanden kennen. Außer du meinst damit den "Glue-Code"
 
Zurück
Oben