Hallo,
ich wollte mich nochmal zur Thematik melden und zur Diskusion betragen. Ich hab nochmal ins Buch geschaut und die Stelle gefunden. Ich hab das Buch in der 2019er Ausgabe. Da ich mir nicht sicher war, ob ich das einfach ablichten und ins Forum stellen darf, hab ich es fix nachgezeichnet. Das Bild hab ich dem Post angehängt, im Buch auf Seite 68, Bild 3.11.
Auf Seite 63 steht auch nochmal:
"Because our goal is to inverse the dependency between the domain layer and the data layer, IProductRepository is defined in the domain layer."
Meine Problematik ist, das ich absehbar vor der Aufgabe stehe, in meiner Anwendung die erzeugten Daten abhängig davon, wer mit der Anwendung arbeitet, zu verarbeiten. Beispielsweise Anwender aus Gruppe A legt beim Betätigen des "Speicher-Buttons" Daten nur lokal ab, Anwender aus Gruppe in der Datenbank. Wenn jetzt Implemetierung A und B in unterschiedlichen Bibliotheken oder Projekten sind, ginge das ja nur so wie oben beschrieben. Wo liegt mein Denkfehler?
Grüße, Alex
Hallo Abt,
danke für deine Antwort. Das Buch heißt "Dependency Injection Principles, practices and patterns" von Mark Seemann.
Dein kurzes Beispiel habe ich in dem Buch genau anders verstanden, nämlich so, dass IUserRepository in der Logikschicht definiert sein muss, damit diese nicht von der Datenschicht abhängt. Sonst müsste ich ja immer die Logikschicht anpassen müssen, wenn sich die Datenschicht andert. Die Datenschicht implementiert dann das Interface. Wenn aber die Datenschicht aus einer anderen Bibliothek stammt, müsste ich da ja noch eine Eben einfügen, die das "anpasst", weil ja das konkrete UserRepository aus der Bibliothek nichts vom Interface meiner Logikschicht weiß. Es gibt ja hier im Forum auch einen Thread zum Thema Schichtarchitektur. Da erwähnt jemand, dass man unter Umständen viel Gluecode schreiben muss, wenn man das konsequent durchzieht. Ist das damit gemeint?
Grüße, Alex
Hallo,
ich lese gerade ein Buch über Dependency Injection und ausgehend davon wird auch Dependency-Inversion und Drei-Schicht-Architektur erwähnt. Ich möchte das ganze nun auch in meinem Projekt anwenden und habe eine grundsätzliche Frage.
Im Buch wird erwähnt, dass die Datenzugriffsschicht von der Logikschickt abhängen soll und nicht andersherum bzw. auch, dass jede Schicht die Interfaces, die sie verlangt, selbst definieren soll.
Frage: Wie mache ich dass, wenn die Datenschicht in einer eigenen Bibliothek vorliegt? Aus dem Bauch heraus würde ich sagen, man braucht eine zusätzliche Vermittlungsschicht, die dann von der Logik- und der Datenschicht abhängt und das dann vermittelt, Stichwort Glue-Code. Wie gesagt, das wäre meine erster Gedanke. Wie ist der "offizielle" Weg?
Grüße, Alex
Hallo Abt,
danke für deine Antwort. Ich habe es jetzt so gelöst, dass eine Methode
IChannelCommunication? GetChannelCommunication(string id);
public interface IChannelCommunication
{
bool IsConnected { get; }
string Id { get; }
void Write(byte[] data);
byte[] ReadPackage();
void Clear();
}
ein Kommunikations-Objekt zurückgibt, das alles beinhaltet, um mit dem Sensor zu reden, aber die Verbindungsfunktionalitat nicht mit veröffentlicht. Die manage ich dann im "Hub".
Grüße, Alex
Hallo Alf,
danke für deine Antwort. Die Repository hat einen Scanner, der die Sensoren sucht und bei einem detektierten Sensor einen Channel erzeugt. Die Channel-Objekte entstehen also im Scanner. Ich habe jetzt folgendes gemacht, ich habe im Scanner eine Methode
Task<byte[]?> SendWaitResponse(string id, byte[] data, IProgress<int>? progress = null);
implementiert. Dann kann ich anhand der Id den Kanal suchen und die Daten schicken und lesen. Der Scanner hält die Channel-Objekte und kann diese dann auch aufräumen.
Hallo,
ich habe folgende Frage:
ich habe eine Klasse welche die Kommunikationsobjekte zu an den Rechner angeschlossen Sensoren verwaltet. Diese Objekte implementieren IDisposable. Wird ein Sensor angeschlossen oder entfernt, wird ein Event ausgelöst. Nun frage ich mich, wie ich am besten das Aufrufen von Dispose() der Kommunikationsobjekte gestalte.
Wenn jetzt die darüberliegende Klasse eine Objekt von der Repository abfragt:
public interface IRepository
{
event EventHandler<ChannelEventArgs>? ChannelAdded;
event EventHandler<ChannelEventArgs>? ChannelRemoved;
ICommunicationChannel? GetChannel(string id);
string[] Channels;
}
public sealed class ChannelEventArgs : EventArgs
{
public string Id { get; }
public ChannelEventArgs(string id)
{
Id = id;
}
}
ICommunicationChannel? channel = _Repsitory.GetChannel(id);
wer ist dann für den Aufruf von Dispose() zuständig? Ich würde jetzt sagen das Repository. Sollte der Channel dann ein Disposed-Event haben?
Danke und Grüße,
Alex
Hallo Abt,
danke für Deine Antwort. Mein Fehler bestand darin, die Android-spezifischen Quellcodedateien nicht im Platforms-Ordner für Android unterzubringen, sondern in einem allgemeinen Ordner.
Danke und Grüße,
Alex
Hallo,
ich habe folgende Frage. Ich habe eine kleines Testprojekt, in dem ich mich mit einem WLAN verbinden möchte. Nach einiger Recherche habe ich rausgefunden, dass das über NetworkRequest und WifiNetworkSpecifier realisert wird. Allerdings bekomme ich den gefundenen Beispiel-Code nicht zum laufen. Es scheitert daren, dass der namespace Android.Net.Wifi nicht gefunden wird. Die Intellisense bietet mit diesen zwar mit dem Verweis "net7.0-android33.0 available" an, trotzdem bekomme ich die Fehlermeldung: CS0246 The type or namespace 'Android' could not be found. Wenn ich das richtig verstanden habe, muss eine Mono.Android.dll referenziert werden. Ich haben nicht rausfinden können, wie? Weiß jemand Rat?
Danke und Grüße,
Alex
Das Model weiß auch so nichts über den Filter, kennt nur das Interface. Messdatenerzeugung, Filter usw. habe ich als Interfaces und Contructor Injection injiziert. Meine Frage ist eher, wie verheirate ich das mit dem Viewmodel.
Hallo Weressated,
ich muss gestehen, dass ich deine Antwort nicht ganz verstehe. Vielleicht habe ich zuwenig Informationen über mein Problem geliefefert. Ich versuche mal, es zu konkretisieren.
In meiner Anwendung geht es darum, dass aus einer Hardware ein Satz Messdaten kommt und der dann verarbeitet werden soll. Das Filtern ist nur eine Schritt davon, der innerhalb der Verarbeitung passiert. So werden die Daten gefiltert, dann mit Referenzwerten verglichen, noch andere Parameter berechnet und viele dieser Dinge müssen einstellbar sein. Es gib also mehrere Klassen, die einstellbare Parameter haben und das möchte ich möglichst sauber umsetzten.