Hallo,
ich muss eine neue Anwendung erstellen und da stellt sich mir die Frage, wie die Projekt (Solution) Struktur ausschauen soll. Da ich in noch nie mit Unity bzw. mit Schnittstellen gearbeitet habe, habe ich ein paar Fragen.
Kurz zur Anwendung, diese um es einfach auszudrücken, verwaltet Listen. Es gibt
In der Datenbank wird nur mit Stored-Procedures gearbeitet. Zum Loggen verwende ich NLog und die Datenbank soll MySQL oder PostgreSQL sein.
Ich möchte das Microsoft Unity benutzen um evtl. Später die Datenbank oder den Logger tauschen zu können. Ich habe mir das Buch sowie nen Webcast zu diesen Thema angeschaut (Unity: Einführung in Dependency Injection und Foundations of Programming Ebook)
Zu meinen Fragen nochmal:
Vielen Dank vorab und Grüße
Hallo ilcsh,
ohne deine Frage im Detail zu beantworten, ein paar Anmerkungen meinerseits:
Beide der Links sind von 2008. Das heißt jetzt prinzipiell erst einmal nichts, aber wenn du ein neues Projekt beginnst, solltest du dir bewusst sein, dass die Links aller Voraussicht nach nicht den aktuellen Stand der Technik widerspiegeln könnten.
3-Schichten Modelle sind grundsätzlich sinnvoll, allerdings würde ich bei einem neuen Projekt zu einem sogenannten ORM (Object-Relational-Mapper) raten. Hier sind vor allem NHibernate und LinqToEntities (Entity Framework, EF) verbreitet.
Beide bieten auch Support für LINQ-Expressions, sodass du zum DB-Zugriff z.B. Code schreiben kannst wie:
Customer customer = context.Customers.Where(c => c.LastName == "Müller").FirstOrDefault();
IMHO erleichtert das die Arbeit mit einer DB erheblich, indem es die Menge an (Infrastruktur-)Code deutlich reduziert.
Zum anderen solltest du unbedingt auch ein Design-Pattern für dein UI verwenden: Unter WPF wäre das meiner Meinung nach am besten MVVM und unter WinForms MVP (in der Ausprägung Passive View - wobei es hier verschiedene Standpunkte gibt).
Die Entscheidung für einen DI-Container ist sehr löblich, evtl. kannst du auch mal einen Blick auf andere Container werfen. Ist nur eine persönliche Ansicht, aber IMHO ist Unity nicht der beste, den es gibt.
Bzgl. Projektstruktur würde ich mir zu Beginn noch keine allzu großen Sorgen machen - das ist etwas, was man später auch noch leicht ändern kann.
Beginnen kannst du z.B. mit vier Projekten:
Hey winSharp93,
danke für deine Antwort.
Ich wollte mit WinForms arbeiten da ich mich mit WPF nicht auskenne.
Wo würden dann die Interfaces reinkommen?
Mit NHibernate und LinqToEntities habe ich noch nie gearbeitet, kannst du mir gute Tutorials auf deutsch empfehlen? Bisher habe ich eine Datenbank Klasse die, die Verbindung zu DB herstellt sowie z.B. DataTable's zurückgibt oder Befehle ausführt, so habe ich es bisher gemacht.
Grüße
Wo würden dann die Interfaces reinkommen?
Kommt darauf an, welche 😉
Generell ist die Aufteilung auf mehrere Projekte vor allem sinnvoll, wenn sich nicht alle gegenseitig referenzieren. Folglich sollten die Interfaces in das Projekt, wo sie Sinn machen - eine Auslagerung in ein separates Projekt würde ich erst durchführen, wenn das tatsächlich benötigt wird (z.B. wenn das DB-System ohne Rekompilierung ausgetauscht werden soll).
Bisher habe ich eine Datenbank Klasse die, die Verbindung zu DB herstellt sowie z.B. DataTable's zurückgibt oder Befehle ausführt, so habe ich es bisher gemacht.
Davon würde ich mich eher verabschieden: DataSets sind zwar in manchen Situationen ganz nett, taugen aber IMHO nicht als Ersatz für Businessobjekte (eingeschränkte Validierungsmöglichkeiten, kein Einbau von Funktionalität möglich, ...).
Mit NHibernate und LinqToEntities habe ich noch nie gearbeitet, kannst du mir gute Tutorials auf deutsch empfehlen
Auf deutsch ist immer so eine Sache... Weitaus mehr findet man auf Englisch.
Spontan bin ich z.B. auf: Zweiter Start mit NHibernate gestoßen - allerdings ist das doch recht oberflächlich.
Davon würde ich mich eher verabschieden: DataSets sind zwar in manchen Situationen ganz nett, taugen aber IMHO nicht als Ersatz für Businessobjekte (eingeschränkte Validierungsmöglichkeiten, kein Einbau von Funktionalität möglich, ...).
Wir handhaben das im Unternehmen so, dass wir ebenfalls eine Schnittstelle verwenden, welche DataSets etc. zurück liefert.
Anschließend führen wir das Mapping auf die Objekte im Code durch. - Ist nicht unbedingt der beste Weg. Aber es funktioniert und ist einfach zu verwenden. Da gibt es zwar noch eine Hintergrundgeschichte zu, aber die ist nicht von relevanz.
Wissen ist nicht alles. Man muss es auch anwenden können.
PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |
Puh, das wird nicht ganz leicht 😃
Ich werde mal versuchen wie weit ich komme 😃
Danke aber euch beiden schonmal ;I
Hallo ilcsh,
wow, du fragst hier Sachen, die Bücher füllen 😉
Grundsätzlich: Verabschiede dich von dem Gedanken, dass du zum Projektanfang eine Struktur festlegst und diese bis zum Ende so bestehen bleibt. Das ist in 99,999% der Fälle nicht möglich. Es kommt immer was dazu, etwas weg, etwas hin oder her und am Ende sieht es anders aus als geplant. Das ist nichts schlechtes, im Gegenteil: Das kann sogar sehr gut sein!
Benutze für das Datenbank-Zeug OR-Mapper oder ähnliches. Wie WinSharp schon sagte. Halte es zumindest seperat.
Bisher habe ich eine Datenbank Klasse die, die Verbindung zu DB herstellt sowie z.B. DataTable's zurückgibt oder Befehle ausführt, so habe ich es bisher gemacht.
Das verstösst konkret gegen das Single-Responsibility-Prinzip. Eine Klasse sollte demnach die Verbindung mit der Datenbank herstellen (etc.) und eine sollte lesen und die Datasets zurückgeben. (Repository, Provider, etc.) Du solltest dir vielliecht mal Patterns allgemein ansehen.
Auch eine n-Schichten-Architektur ist nichts schlechtes, also fährst du sicher mal gut damit. Ob du nun die Klassen flach in das Projekt legst oder in Namespaces machst, eventuell sogar noch die Implementationen in eigene Namespaces legst und die Interfaces heraus: Das musst du wissen. Stichwort "Clean-Code".
Wenn du eine Schicht dem kompletten Projekt anbietest und nicht willst, dass die Schicht darüber etwas von der Implementation der Schicht darunter weiss, kannst du auch ein eigenes Interface-Projekt machen. Dann wird nur das referenziert. Das Impl-Projekt implementiert dann die Interfaces aus.
Login: Könnte ein Service machen, braucht aber auch UI. VM könnte den Service injected bekommen.
Main: UI: Zeigt Listen an, Service ins VM injecten, der dir die Listen anbietet, dann auf dem VM anbieten und im UI anzeigen
Export / PDF: Könnte ein PDF-Service machen. Braucht kein UI, solltest du aber getrennt halten (Interface, Implementation)
und und und...
Das sind nur Vorschläge, wie man es machen könnte, es gibt etliche Möglichkeiten
Fazit: Es gibt viele viele Möglichkeiten dahin zu kommen, wo du hinmagst. Welche letztendlich die Beste für dich ist, musst du wissen. Clean-Code, Single-Responsibility, Repository-Pattern, MVVM, und und und sind sicherlich Hilfen.
Setz dich damit mal auseinander
Gruss
Coffeebean
PS:
Ich wollte mit WinForms arbeiten da ich mich mit WPF nicht auskenne.
MVVM hat eine recht "saubere" Architektur was den UI Part angeht. Und schwer ist es auch nicht. Schau es dir mal an 😉
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Hey Coffeebean,
danke für deine Antwort.
Ich habe laange so Programmiert (Arbeit, mehr möchte ich hier nicht eingehen, ich möchte mich selber weiterbilden da ich dort keine Unterstützung erhalte (in Form von Bücher, Zeit etc.)):
Ich habe mir das NHibernate mal angeschaut.
Habe ich das richtig verstanden, meine Tabellen sowie derren Spaltennamen, erstelle ich in Klassen? Ist das auch empfehlenswert wenn ich SQLite verwenden möchte?
Was ich noch nicht verstehe, ich hatte Stored Procedures, kann ich die hier vergessen?
Wie schaut es aus wenn ich abfragen wie Inner Join habe?
Ich habe mir das jetzt anfangs so vorgestellt:
Projekt -> Hier ist die UI (WPF oder WinForms)
Projekt.Service -> Die ganzen Interface
Projekt.Domain -> Da sind die Klassen der DB (NHibernate )
Projekt.Repository -> Hier werden die Klassen erstellt (durch die Interfaces)
Habe ich das richtig verstanden, meine Tabellen sowie derren Spaltennamen, erstelle ich in Klassen? Ist das auch empfehlenswert wenn ich SQLite verwenden möchte?
Was ich noch nicht verstehe, ich hatte Stored Procedures, kann ich die hier vergessen?
Wie schaut es aus wenn ich abfragen wie Inner Join habe?
Grundsätlich funktioniert NHibernate mit so ziemlich allen DB-Systemen, mit recht großer Sicherheit auch mit SQLite. Du kannst das DBMS dann auch später recht einfach austauschen.
Im Prinzip trifft es dann schon: Je Tabelle eine Klasse, je Spalte ein Feld. Gibt aber auch komplexere Mappings für Vererbung etc. Wenn du eine genauere Frage hadt, am besten in Datentechnologien stellen.
Für den Anfang bietet sich evtl. ein kleines Testprojekt an, in dem du etwas den Umgang mit Nhibernate übst.
Stored Procedures kannst du zwar einbinden, ich würde aber im Normalfall nicht dazu raten, diese allzu exzessiv einzusetzen. Führt meist zu versteuter Anwendungslogik, schlecht gemanagetem SQL-Code (Versionsverwaktung usw. wird da gerne mal eingespart) und anderen Problemen.
Ich habe mir das jetzt anfangs so vorgestellt:
Was sollen wir groß sagen?
Klar - ist eine Möglichkeit. Wie gesagt: Die "richtige" Lösung gibt es nie.
Die Namensgebung des Repository Projektes ist aber IMHO etwas verwirrend, da ein Repository im Normalfall eine Klasse für den DB-Zugriff darstellt.
Klar - ist eine Möglichkeit. Wie gesagt: Die "richtige" Lösung gibt es nie.
Die Namensgebung des Repository Projektes ist aber IMHO etwas verwirrend, da ein Repository im Normalfall eine Klasse für den DB-Zugriff darstellt.
Upps, ok. Danke.
Wenn ich das jetzt so in etwa aufteile, habe ich schonmal ne grobe Struktur 😃
Und damit sollte das Ziel des Threads erfüllt sein, bevor das hier ein Sammel-Thread zu allen Fragen um Software-Architektur wird, siehe [Hinweis] Wie poste ich richtig? Punkt 1.2. Ansonsten ist das - wie Coffeebean schon andeutete - ein Fall für ein oder mehrere Bücher.