Laden...

Circular Dependency C# .NET

Erstellt von casiopeia vor 13 Jahren Letzter Beitrag vor 13 Jahren 7.966 Views
C
casiopeia Themenstarter:in
47 Beiträge seit 2007
vor 13 Jahren
Circular Dependency C# .NET

Hallo,

hab folgendes Problem Assembly A und Assembly B. Assembly A hat eine Referenz zu Assembly B. Nun müsste ich aber von Assembly B auf die Assembly A zugreifen. Wie kann ich das machen?

Gruss Casiopeia

3.430 Beiträge seit 2007
vor 13 Jahren

Hallo,

wenn du sowas machen musst dann ist etwas an deiner Software-Architektur falsch.
Denn sowas darf und kann man nicht machen.

Und es ist in der Objektorientierung auch nicht nötig 😃

Gruß
Michael

L
416 Beiträge seit 2008
vor 13 Jahren

Grundsätzlich genauso wie hier: [FAQ] Kommunikation von 2 Forms

799 Beiträge seit 2007
vor 13 Jahren

Jo, also das was in A und B gebraucht wird, lager aus nach C und binde das dann in deinen Projekten ein.

As a man thinketh in his heart, so he is.

  • Jun Fan
    Es gibt nichts Gutes, außer man tut es.
  • Erich Kästner
    Krawutzi-Kaputzi
  • Kasperl
W
955 Beiträge seit 2010
vor 13 Jahren

Eine weitere Möglichkeit wäre ein IOC-Container/Service Locator oder ein plugin-Framework wie MEF

6.862 Beiträge seit 2003
vor 13 Jahren

Hallo,

die Verwendung von IoC ändet ja nichts an der Grundproblematik. Da ist die einzige Lösung die, die der-schlingel gepostet hat - Gemeinsames auslagern und dann referenzieren.

Baka wa shinanakya naoranai.

Mein XING Profil.

W
955 Beiträge seit 2010
vor 13 Jahren

die Verwendung von IoC ändet ja nichts an der Grundproblematik. Da ist die einzige Lösung die, die der-schlingel gepostet hat - Gemeinsames auslagern und dann referenzieren. So? wie löst Du dann MVVM? Das View-Assembly referenziert das Application-Assembly, in dem die ViewModels lagern, damit das Binding funktioniert. Wie kann jetzt aber auf Applicationsebene entschieden werden dass ein neuer View anzuzeigen ist? Ich meine das App-Assembly kann doch gar nicht das konkrete View kenn das es das View-Assembly nicht referenzieren kann?

799 Beiträge seit 2007
vor 13 Jahren

Aber das App-Assembly wird wohl kaum irgendwelche Interfaces oder Klassen enthalten die das View-Assembly benötigt. Das heißt so gibt es keine Kreise bei den Referenzierungen. Das ist ja das Problem: A benötigt B und B benötigt A. Das mag der Compiler gar nicht.

As a man thinketh in his heart, so he is.

  • Jun Fan
    Es gibt nichts Gutes, außer man tut es.
  • Erich Kästner
    Krawutzi-Kaputzi
  • Kasperl
W
955 Beiträge seit 2010
vor 13 Jahren

Wenn man bei MVVM die Views und die ViewModels in zwei Assemblies splittet hat man sehr wohl ein zirkuläres Problem. Ich wollte sagen dass das nicht immer ein Modellierungsfehler sein muß.
Ich habe das mit dem WAF gelernt: im App-Assembly werden ViewSchnittstellen erstellt:


public interface IMainView: IView

  void Show();
}

Diese werden in der ViewAssembly von den Views "implementiert":


public partial class MainView : Window, IMainView
{
}

Dieses ist nötig damit auf der App-Ebene das View angezeigt werden kann. Somit muß das View-Assembly das App-Assembly kennen damit es etwas mit IMainView anfangen kann.
Damit haben wir eine zirkuläre Referenz, die halt mit IOC etc aufgelöst wird.

3.430 Beiträge seit 2007
vor 13 Jahren

Hallo,

Damit haben wir eine zirkuläre Referenz, die halt mit IOC etc aufgelöst wird.

Das Problem ist ja dass das Projekt B eine Referenz auf Projekt A hat.
Und das Projekt A hat eine Referenz auf Projekt B

Das ist nicht möglich da das dem Compiler nicht schmeckt.
Ob du da jetzt IoC verwendest oder nicht ändert relativ wenig an dem Problem.
Die einzige Möglichkeit ist das irgendwie auszulagern.

Gruß
Michael

W
955 Beiträge seit 2010
vor 13 Jahren

Die einzige Möglichkeit ist das irgendwie auszulagern. Nein, ich lasse in meinem Fall das App-Assembly von der View-Assembly referenzieren und verwende beim Öffnen eines Forms einem Ioc/Service Locator: "Bitte gib mir ein Exemplar welches IMainView implementiert und rufe Show() auf"
Bin ich denn der einzige der dieses Problem hat? Wie löst ihr das Problem?

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo witte,

ich bin kein MVVM-Spezialist, aber im Grunde ist das ja nur eine Frage der Trennung von Modell und GUI. Wenn App-Assembly == Model-Assembly, dann ist das was du beschreibst, sicher der falsche Weg. Das Modell sollte keine Views kennen auch nicht über Interfaces. Es sollte nicht mal wissen, dass es sowas wie Views oder Fenster gibt. Wenn das Modell meint, sein Aufrufer/Benutzer (also das GUI) müsse über bestimmte Situationen oder Konstellationen informiert werden, sollte es ein entsprechendes eigenes Event werfen. Letztlich entscheidet dann aber das GUI, ob es angemessen ist, als Reaktion auf das Event ein Fenster zu öffnen oder nicht. Was tatsächlich passiert, hat das Modell nicht zu interessieren.

Hallo zusammen,

nochmal generell: Natürlich kann es Fälle geben, in denen unmittelbar zusammengehörende Klassen (z.B. TreeView und TreeNode) wechselseitig voneinander abhängig sind. Quasi untrennbar verbunden. Die eine Klasse macht jeweils ohne genau die andere Klasse keinen Sinn. Solange sich die beiden Klassen in einer Assembly befinden - und das sollten sie, wenn sie wirklich so eng zusammengehören -, ist das auch kein Problem.

Zyklische Abhängigkeiten zwischen verschiedenen Assemblies sollte man aber - wie schon mehrfach gesagt - unbedingt auflösen bzw. vermeiden. Dazu gibt es im wesentlichen zwei Wege, die beide auch schon genannt wurden: Auslagern von gemeinsamen Teilen in eine gemeinsam benutzte Assembly. Oder verwenden von Events, um eine direkte Abhängigkeit in eine der beiden Richtungen zu entfernen. Welchen der beiden Wege man verwendet hängt von den Umständen und der Art der Abhängigkeit ab. In einer bestimmten Situation wird meistens wohl nur jeweils einer der Wege überhaupt passen.

So nützlich und sinnvoll IoC im allgemeinen ist. Wenn zyklische Abhängigkeiten zwischen zwei Assemblies nur durch IoC aufgebrochen werden, wäre ich skeptisch. Ich kann mir momentan keinen Fall vorstellen, wo das Sinn machen würde.

herbivore

W
955 Beiträge seit 2010
vor 13 Jahren

Hallo,

nein, das Modell und die Geschäftslogik befindet sich in einem anderen Assembly. Das Modell hat hier gar nichts zu suchen. Mit App-Assembly meine ich die treibenden Komponenten der spezifischen Anwendung, also die Controller (ApplicationController und modulspezifische Kontroller), die ViewModels die abstrakte Views beschreiben und die Services mit denen beispielsweise Repositories verfügbar sind.

H
114 Beiträge seit 2007
vor 13 Jahren

Hallo,

Wenn man bei MVVM die Views und die ViewModels in zwei Assemblies splittet hat man sehr wohl ein zirkuläres Problem.

Aber wieso sollte man das wollen? Also ich bin nun ebenfalls kein Experte beim Thema MVVM, aber ein ViewModel gehört doch sowieso immer zu einer View. Wieso dann also die beiden zusammengehörigen Teile nicht gleich in eine Assembly packen?

Würde mich demnach der Aussage von herbivore anschließen...

Solange sich die beiden Klassen in einer Assembly befinden - und das sollten sie, wenn sie wirklich so eng zusammengehören -, ist das auch kein Problem.

Grtz

W
955 Beiträge seit 2010
vor 13 Jahren

Hi,

ich möchte andere nicht zum schlechten Design verleiten noch alle mögliche auseinanderreißen (TreeView und TreeViewItem).
Es ist jedoch bei den verschiedenen MVVM-Frameworks häufiger üblich die beiden Sachen zu trennen, schließlich soll ja das ViewModel die konkrete View nicht kennen, den dann können wir ja gleich wieder MVC machen. Es erleichtert u.U. auch die Zusammenarbeit zwischen Entwickler und Designer.
Ich finde es nebenbei gesagt etwas komisch das ihr diese Vorgehensweise verurteilt ohne sich vorher mit dieser Technik auseinandergesetzt zu haben.

F
10.010 Beiträge seit 2004
vor 13 Jahren

Wir verurteilen nicht die herangehensweise View und ViewModel zu trennen, denn das macht Sinn, sondern wir verurteilen die Tatsache das du nicht verstehen willst das jedwede circulären Herangehensweisen schlecht sind.

Wird tatsächlich von A etwas in B benötigt und von B etwas aus A, ist etwas schief gegangen in dem Design.
Beide sollten nur über C ( ggf reine Interface DLL ) voneinader wissen.
Und auch ein DI/SL sollte weder in A noch in B sitzen.
So hat man eine saubere Trennung und keine " Circular Dependency "

U
282 Beiträge seit 2008
vor 13 Jahren

Es ist jedoch bei den verschiedenen MVVM-Frameworks häufiger üblich die beiden Sachen zu trennen, schließlich soll ja das ViewModel die konkrete View nicht kennen,

Genau. Also gibt es drei Assemblies. ViewModel, ViewImpl und ViewIterface. Die Abhängigkeiten sind dann

ViewModel --> ViewInterface
ViewImpl --> ViewModel, ViewInterface

Und nirgends ist etwas zirkuläres.

6.862 Beiträge seit 2003
vor 13 Jahren

Hallo,

Wenn man bei MVVM die Views und die ViewModels in zwei Assemblies splittet hat man sehr wohl ein zirkuläres Problem. Ich wollte sagen dass das nicht immer ein Modellierungsfehler sein muß. Doch, es ist immer ein Fehler. Code mit zirkulären Referenzen ist nicht kompilierbar, daran ändert auch IoC nichts. Das kommt ja erst zur Laufzeit ins Spiel, aber soweit wird man ja gar nicht kommen.

Somit muß das View-Assembly das App-Assembly kennen damit es etwas mit IMainView anfangen kann.
Damit haben wir eine zirkuläre Referenz, die halt mit IOC etc aufgelöst wird. Nein, wie Uew81 auch gezeigt hast, hast du ne Referenz von View auf ViewModel, aber nirgends referenziert das ViewModel auf die View. Da du WAF ins Spiel gebracht hast - guck dir einfach mal in den Beispielen die mitkommen an wie die Teilprojekte einer App sich gegenseitig referenzieren - nirgends eine zirkuläre Referenz.

Baka wa shinanakya naoranai.

Mein XING Profil.

W
955 Beiträge seit 2010
vor 13 Jahren

Hi,

@talla: welches Beispielprojekt meinst du genau? BookLibrary, EmailClient und Writer haben nur zwei Assemblies, eine für View(Presentation) und eine für die Application (Model und Tests sind weitere Assemblies). Dort wird diese Vorgehensweise genauso gemacht, von dort habe ich es ja.

Aber Uwe81 hat ja eine einfache Möglichkeit gepostet wie das umgangen werden kann...

6.862 Beiträge seit 2003
vor 13 Jahren

Hallo,

ja die mein ich, aber wo siehst du da die zirkuläre Referenz? Das Viewmodel referenziert nicht die View.

Baka wa shinanakya naoranai.

Mein XING Profil.

W
955 Beiträge seit 2010
vor 13 Jahren

Hi,

nein, natürlich können da keine zirkuläre Referenzen sein, dass würde VisualStudio schon beim Anfügen von Referenzen prüfen und verbieten.
Es ging darum dass man ein SL oder was allgemein mit Reflection zur Laufzeit Objekte verbinden kann, nicht mißbrauchen sollte. Ich lediglich stand vor dem Problem (wie in diesen Beispielapps): Die View referenziert die App, die App muß aber Views anfassen können, beispielsweise ein neues Window öffnen. Das habe ich mit zirkulärer Abhängigkeit gemeint.
Ich wollte keineswegs sagen dass ein SL oder was uach immer einen Freibrief darstellt auch wenn es so rübergekommen ist. Ich wollte nur sagen, ich kenne da ein spezifisches Problem: V <-> VM.