| 

.NET C# Java Javascript Exception

5
Hallo,

ich möchte hier einmal die Vor- und Nachteile eines direkten Zugriffs einer WinForms-Anwendung auf eine Datenbank diskutieren und eure Meinungen erfahren.

Szenario:
Eine WinForms-Anwendung wird an ca. 20 - 40 Benutzer verschiedener Firmen verteilt.
Diese Anwendung holt Daten aus einer Datenbank (wahrscheinlich SQL-Server Express 2008 R2) und zeigt diese in GridViews an. Vereinzelt können die User Änderungen durchführen.
Die Datenbank liegt auf einem Root-Server eines Hosting-Anbieters.

Daten werden über SQL-Anweisungen direkt von der DB angefordert (SQLCommand, DatatTable, DataAdapter).
Alle Installation kommunizieren mit einem und dem gleichen DB-User.
Die Kommunikation zur Datenbank wird verschlüsselt (Einstellung im SQL-Server), somit wird auch das DB-USer-Passwort nicht im Klartext übertragen.

Klar, die Firmen müssen jeweils einen Port freigeben. Das ist ein echtes Manko.

Aber was würde sonst noch dagegen sprechen?
Ich halte die Lösung für einfach aber machbar.

Dem gegenüber würden aufwendige Programmierungen mit Entitiy Framework und oder WebServices (z.B. WCF) stehen.
Nichts gegen WebServices, aber ich möchte in vertretbare Zeit zu einem Ziel kommen! :-)

Ich bin gespannt auf eure Meinungen.

Viele Grüße

Maik
20.08.2013
Maik_1978 674 1 8
Warum muss es eigentlich eine Desktop-Anwendung sein?
phg 20.08.2013
2 Antworten
5
Vorgeschichte

Bei der Festlegung der Architektur sind wir von folgenden Umständen ausgegangen:

  • Windows Forms Anwendungen sind einfacher und schneller zu erstellen.
  • Es gibt eine Vielzahl von Steuerelemente, die man zum Einbinden in die eigene Anwendung hinzuziehen kann
  • Viele Opensource-Projekte verwenden diese Form der UI
  • Es lassen sich einfacher Installations-Routinen erstellen
  • Ein Framework für eine kleine Anwendung incl. Datenzugriff (dOOdads) wurde präsentiert.

Gegen die Verwendung und Implementierung einer Client-Server-Anwendung sprach:

  • Das Erstellen einer Schichten-Architektur ist aufwendig
  • Die Kommunikation zwischen den Schichten erscheint zunächst sehr kompliziert

Also wurde die Entscheidung getroffem: Wir erstellen eine WinForms-Anwendung mit direktem Zugriff auf die Datenbank. Jeder Client beinhaltet die vollständinge Logik und braucht daher zu Zugriff zur Datenbank (in unserem fall MS SQL Express).

Sofort wurde begonnen die Implementierung anzupassen. dOOdads als Datenzugriff schied nach einiger Zeit wieder aus, da das Arbeiten mit diesem Abtraction-Layer nicht vollständig implementiert war. Wir begannen daher eine eigene Idee für den Datenzugriff zu entwickeln.

Als die groben Implementierung abgeschlossen waren, wurde das Designziel "VPN-Optimiert" hinzugefügt. Das bedeutete, das der Zugriff durch ADO.NET/DataSet-Techniken völlig ungeeignet waren: Bevor wir Daten sortiert anzeigen können, müssen diese komplet geladen werden (über eine langsame VPN-Verbindung) um dann von der Logik auf dem Client entsprechend verarbeitet werden zu können. Bei der schon damals hohen Anzahl von Artikel-Datensätzen (circa 12.000 Artikel incl. 1 - 3 Preisinformation pro Artikel) ein völlig danebenliegenden Ansatz.

Es kam zu einer weiteren Entscheidung: Da wir schon viel Funktionalität implementiert hatten, wurde entschieden, dass wir eine eigene "VPN-Optimierung" entwickeln. Es wurden daher zwei Entwicklerteams berufen: eines für die Funktionalität der Anwendung und eines für die VPN-Optimierung.

Die ersten Ansätze sahen sehr erfolgversprechend aus: Der Client soll aus der Anfrage des Moduls einen passenden SQL-String erzeugen. Dieser würden dann an die Datenbank gesendet und das Ergebniss würde dann zurückkommen. damit wurde die eigentliche ADO.NET/DataSet-Technologie von uns "abgeschaltet".

Doch leider stellte sich heraus, dass damit andere Probleme auftauchten: Nachlaen von Daten, Paging bei großen Listen, Mitteilung über Änderungen usw. Jedesmal wurde viel Zeit invenstiert, um ein Problem zu beheben - als Ergebniss kamen dann oft weitere Probleme oder es waren Einschränkungen in der Funktionalität.

Das eigentliche K.O. kam dann, als nach einem notwendingen Optimierungsversuch, der Datenzugriff nicht mehr funktional gewesen ist. Die Ursache wurde nach wochenlangen Suchen nicht gefunden. In einer entscheidenden Besprechung wurden dann das cshon erreichte dem gegenüber gestellt, was noch zu tun ist und ob die Möglichkeit besteht, dass wir die "VPN-Optimierung" hinbekommen. Als Ergebniss wurde gemeinsam beschlossen: Eine Weiterentwicklung in dieser Form ist nicht tragbar.

Neuanfang

Anfang 2013 wurde das ganze Konzept von vorn begonnen. Man einigte sich darauf, das aktuelle Techniken was Architektur und UI betrifft, Verwendung finden soll. Außerdem soll der Aufwand, was Eigenentwicklungen betrifft, sich nur auf das Nötigste beziehen. Sobald es eine passende Alternative (auch kostenpfliuchtige) gibt, wird dies in Erwägung gezogen, da meistens auch ein entsprechender Support dabei ist.

Wir entschieden uns daher für folgende Techniken oder Produkte:

  • Datenbanksystem: MS SQL Express 2012
  • Reportsystem: MS SQL Express 2012 - Reporting Services
  • Allgemeine Architektur: Clients greifen auf einen Anwendungsserver zu, der vor der Datenbank steht
  • Kommunikation zwichen Client und Server: Zyan
  • Datenzugriffsschicht: Entity Framework 4.1 STE
  • Client-UI: WPF, Extended WPF Toolkit und NavigationPane
  • Modularität: MEF

Durch die Verwendung dieser Techniken und Produkte ist es uns seit dem immer wieder möglich gewesen, dass wir bei bestimmten Fragen uns an die entsprechende Community wenden konnten. Da wir z.B. das gängige MVVM-Pattern nutzen und viele produkte damit "werben", dass sie MVVM unterstützen, konnten wir bis jetzt in einem Bruchteil der Zeit eine vielzahl an Funktionalitäten einbringen, die mit Windows Forms Anwendung nur sehr umständlich nachzubilden gewesen wäre.

Fazit

Die Entscheidung für den Neubeginn war 100% richtig. Die Anwendungsstruktur in Visual Studio ist tatsächlich komplexer geworden. Und jedes neue Modul, was wir entwicklen müssen, besteht aus mindestens 10 einzelen Klassen-/WPF-Projekten. Aber die Wiederverwendbarkeit und die Erweiterbarkeitet sind deutlich gestiegen. Was die Zukunft betrifft kann unsere neue Architektur auch weiterbestehen, wenn es neue UI-technologien gibt: Wir tauschen nur die Präsentations-Schicht gegen das neue UI aus und können so auch zukünftig noch unsere Funktionen anbieten bzw. uns den verschiedensten Anforderungen anpassen.
20.08.2013
MyKey0815 1,6k 2 9
6
Aber was würde sonst noch dagegen sprechen?

Ich fürchte, so einiges...

Die größten Bedenken hätte ich wegen des gemeinsamen DB-Users (und ich lese Deine Beschreibung so, daß es ansonsten keine Logins auf Anwendungsebene gibt). Wenn dessen Zugangsdaten in die falschen Hände gelangen, besteht die Gefahr, daß

  • ein Unbefugter Kenntnis von Euren Daten erlangt
  • jemand die Daten ändert, u.U. sogar ohne daß das gleich bemerkt wird
  • die Verfügbarkeit Eures Dienstes beeinträchtigt wird, sei es durch Löschen der Daten oder böswillige SQL-Abfragen zu Lasten der Performance

Was das im einzelnen für Euch bedeuten würde, müßtet ihr Euch überlegen. Bei einer Anwendung mit kommerziellem Hintergrund kann ich mir aber nicht vorstellen, daß nicht wenigstens einer dieser Punkte die Gefahr beinhaltet, daß jemand Geld verliert, gekündigt wird oder vor dem Richter landet.
Zwar könnten Login-Daten auch kompromittiert werden, wenn jeder Benutzer sein eigenes Login hätte, aber dann kannst Du viel leichter diesen Benutzer verantwortlich machen, zur Vorbeugung die Paßwörter regelmäßig ändern lassen oder im Schadenfall einen Account sperren, ohne die ganze Anwendung dicht zu machen. Und was macht ihr, wenn einer Eurer Kunden nicht mehr Kunde sein will oder soll? Wie stellt ihr sicher, daß nach Ende der Geschäftsbeziehung der Zugang zu Eurer DB nicht mißbraucht wird?

Von daher würde ich aus Sicherheitsgründen unbedingt für benutzerbezogene Logins plädieren. Auch sonst könnte irgendwann mal ein Kunde oder Dein Produktmanager mit der Anforderung daherkommen, daß neue Rollen (z.B. ein eingeschränkter, nur lesender Zugriff) unterstützt werden sollen. Dann brauchst Du sowieso mehrere Benutzerkonten. Deutlich aufwendiger wird dann aber natürlich die Benutzerverwaltung. Vor allem läßt sie sich, soweit ich sehe, nicht so ohne weiteres in die Anwendung integrieren (z.B. Selbst-Registrierung neuer Benutzer).

Damit sind wir auch schon beim nächsten Punkt: direkter Zugriff der (client-seitigen) Anwendung auf die DB. Performance-/Skalierungsprobleme (Stichwort: gleichzeitig offene DB-Verbindungen) dürften bei Euren Nutzerzahlen (erst mal...) keine Rolle spielen. Aber Dir muß klar sein, daß Du kaum erzwingen kannst, daß Eure DB nur über Eure Anwendung aufgerufen wird statt über irgendein DB-Tool wie SQL-Plus. Rechte- und Rollenkonzepte mußt Du also in der Sprache von DB-Objekten ausdrücken können statt in Anwendungsfällen (es sei denn, Du implementierst die Anwendungsfälle als stored procedures in der DB). Das kann (jetzt oder in Zukunft) eine Einschränkung sein, muß es aber nicht. (Da kenne ich mich wenig aus, aber z.B. etwas nach der Art "darf alle Datensätze lesen, aber nur die ändern, die er selbst angelegt hat" stelle ich mir schon schwierig vor, und "darf neue Bestellposition nur dann anlegen, wenn damit der Gesamtumfang der Bestellung das benutzerspezifische Limit in Tabelle XYZ nicht übersteigt" wäre wohl auf keinen Fall möglich.) Umgekehrt kann es auch ein Vorteil sein, auf diese Weise die (bei den großen Anbietern in der Regel sehr ausgereiften) Security-Mechanismen der DB nutzen zu können, als selbst in einer serverseitigen Anwendungsschicht nochmal eine wasserdichte Authentifizierung implementieren zu müssen.

Und schließlich die Frage der Technologie. OR-Mapper wie EF oder NHibernate haben DataSets und -Tables nicht ohne Grund den Rang abgelaufen. Diese eng ans UI gekoppelten, für schnelle / "kurze" Netzverbindungen und vor allem RAD-Ansätze gedachten Objekte haben / hatten zwar durchaus ihre Daseinsberechtigung, aber eben auch ihre Grenzen, die leider nicht immer sofort sichtbar sind. Die Antwort von @MyKey0815 läßt da manches anklingen. Da kommt es aber auch stark auf den Einzelfall an. Wenn ihr viel Know-How und Erfahrung mit DataTables habt und die Mengengerüste überschaubar sind, auf der anderen Seite OR-Mapper komplettes Neuland wären, könnte die "alte" Technologie für Euch besser geeignet sein. Im allgemeinen würde ich aber immer eine saubere Trennung zwischen UI und Datenzugriff anstreben, und die ist mit DataTables nicht zu kriegen. Der Vollständigkeit halber: wenn Eure Anwendung hauptsächlich Datenabfragen macht und kaum etwas schreibt, auch kein ausgefeiltes Objektmodell hat, das ein OR-Mapper auf die DB abbilden müßte, würde ich auch mal über einen selbst geschriebenen DB-Zugriff mit SqlReader & Co, also ganz einfach, nachdenken.

Fazit:

  • unbedingt benutzerspezifische Logins implementieren - entweder durch benutzerspezifische DB-User oder Logins auf Anwendungsebene mit einer serverseitigen Anwendungsschicht vor der DB
  • Technologie für DB-Zugriff hinterfragen. Tragfähigkeit einer DataTable-Lösung kritisch durch Spikes und Untersuchung der möglichen zukünftigen Entwicklung der Anwendung absichern und mit Alternativen vergleichen.
  • nur die DB auf Serverseite zu haben, kann dann durchaus eine vernünftige Lösung ergeben. Kriterien wären dann, ob die Verwaltung der DB-User technisch und organisatorisch machbar ist, und ob rein DB-bezogene Rechte- und Rollenkonzepte als (auch zukünftig) ausreichend erachtet werden.
20.08.2013
Matthias Hlawatsch 13,2k 4 9

Stelle deine Programmieren-Frage jetzt!