MVVM ProjectTemplate für Visual Studio

    • VB.NET

    Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von Nofear23m.

      MVVM ProjectTemplate für Visual Studio

      Hallo Leute

      Da es bei MVVM Projekten wenn man diese korrekt aufteilen möchte eine gewisse Projektstruktur innerhalb der Projektmappe notwendig ist, ist einigen sicher bekannt.
      Wem das Pattern MVVM kein Begriff ist kann dieses hier gerne nachlesen.

      Um das Pattern zum einen einzuhalten und das Projekt auch für Unittests tauglich zu machen gibt es einige Dinge zu beachten, das wichtigste dabei ist wohl das gewisse Schichten voneinander abgekoppelt sind. So z.b. das das ViewModel die View nicht kennt, also keinen Verweis darauf besitzt. Eine MVVM Projektmappe sieht im minimalfall wie folgt aus:
      • APP (WPF Anwendung)
      • MODEL (Klassenbibliothek)
      • VIEWMODEL (KLassenbibliothek)
      • VIEW (WPF Benutzersteuerelementbibliothek)
      • UNITTESTS (Optional: Unittests Projekt)

      Wer schon das ein oder andere Projekt im MVVM Stil aufgesetzt hat weis das es eine stupide Arbeit ist die Projektmappe so aufzusetzen. Die ganzen Projekte (Klassenbiblitotheken, WPF Start-Projekt, WPF Usercontrol-Biliothek) erstellen, die Verweise setzen, auf die Namenskonvention achten damit am Ende die Namespaces sprechend sind usw. Anschliessend muss man dann auch noch alle Verweise auf die Projekte gegenseitig setzen. Z.b. benötigt das ViewModel einen Verweis auf das Model, die View einen Verweis auf das ViewModel usw.
      Aus diesem Grund dachte ich mir nun endlich mal das ich mir nun mal ein Template erstelle. In diesem Template ist aber nicht nur die Projektstruktur ansich enthalten sondern noch ein wenig mehr. Aber erstmal hier ein Screenshot und eine erklärung:



      Ist das Template in Visual Studio implementiert indem man das ZIP-File (im unentpacktem Zustand) in das Visual-Basic Template Verzeichnis kopiert, kann das Template ausgewählt werden.
      Der Pfad für die Templates befindet sich im Regelfall unter: C:\Users\%username%\Documents\Visual Studio 2019\Templates\ProjectTemplates\Visual Basic


      Nach einem klick auf "Weiter" kann man nun den Namen des Projekts angeben. Dieser Name wird dann sowohl für die Projektmappe (Solution) verwendet als auch für jedes der Projekte welche in dieser Projektmappe angelegt werden gefolgt von einem Punkt und der Layerbezeichnung (Model, ViewModel, View, App). So sind auch die Namespaces gut strukturiert und man hat wieder schön Ordnung.

      Weiters habe ich implementiert das auch das Framework gewählt werden kann, runter bis .Net Framework 4.5.
      Klickt man auf "Erstellen" wird die Projektmappe mit allen Projekten erstellt und alle Verweise gesetzt.

      Nun gibt es zwei Templates. Das eine erstellt die reine MVVM Struktur und das zweite (größere File) erstellt die MVVM Struktur inkl. ein paar Klassen auf welche ich gleich noch eingehen werde.



      Das Projekt sollte nun so wie es ist bereits kompilieren und ein MVVM Projekt erstellen welches voll funktionsfähig ist ohne ein MVVM Framework oder andere NuGet-Pakete von Drittanbietern zu verwenden.

      Zusätzliche Klassen im Projekt:

      ViewModel-Projekt

      Eine RelayCommand Klasse welche das hantieren von und mit Commands erhablich vereinfach
      Eine ViewModel-Basisklasse inkl. einer Eigenschaft VMisBusy welche verwendet werden kann um den User später einen Ladebalken oder ähnliches zu zeigen.

      Ein ServiceContainer welcher als Signleton implementiert wurde und dazu dient Service-Instanzen zu "halten". Services werden in der Welt von MVVM dazu verwendet um Teile der View über DependencyInjection zu Abstrahieren. Beispielsweise kann damit realisiert werden das man vom ViewModel auf ein Fenster öffnen kann ohne dieses zu kennen da die View oder die App ja gänzlich unbekannt ist. Aber auch für UnitTests hat dies eine wichtige Bedeutung. Aber weiter
      Ein IWindowService (Interface) welches an dieser stelle im Grunde nur al Beispiel für ein Service dienen soll. Diese implementierung eines Service kann ein Fenster öffnen lassen und dabei einen Datenkontext zuordnen, wie dies implementiert ist dazu später mehr.


      View-Projekt

      In diesem Projekt gibt es nur ein Objekt. Ein Window mit dem Namen SPSWindow. Dies ist ein Window mit ein paar Erweiterungen um den Umgang in einer MVVM Umgebung ohne einem MVVM Framework erheblich zu vereinfachen. Dieses Window dient in meinen Anwendungen immer als "Default"-Window. Also für Dialoge, oder sonstige Fenster welche ich irgendwo öffnen möchte.
      Aber diese Funktionalitäten könnt ihr euch in der CodeBehind des Window ansehen und bei Fragen hier einfach Antworten.


      Model-Projekt

      Auch hier gibt es lediglich eine Klasse. Die ModelBase Klasse. Diese hat einfach ein paar Eigenschaften und Methoden welche in fast jedem Projekt in einer Basisklasse verwendet werden und ist als Serializable gekennzeichnet. Die Eigenschaften sind sicher selbsterklärend. Die Methoden Validate und IsValid können ein Model egal welcher Art validieren sofert DataAnnotations gesetzt wurden.


      App-Projekt

      Die Klasse WindowService implementiert nun das IWindowService Interface aus dem ViewModel-Projekt um die Funktionalität zu "injezieren" und sollte wenn man den Code so durchgeht auch selbsterklärend sein. Wie gesagt, sonst einfach Fragen. Diese Klasse verwendet nun auch das im View-Projekt vorhandene SPSWindow und dessen Methoden welche sich im CodeBehind befinden. Über diese Art der implementierung kann ein Fenster später über dessen ViewModel gesteuert werden was einen sehr hohen Komfort beim umgang mit Fenstern und Dialogen liefert.

      In der Application.xaml.vb wurde die Methode Application_Startup generiert und lediglich mit folgender Zeile befüllt:

      VB.NET-Quellcode

      1. ViewModel.Services.ServiceContainer.Instance.AddService(Of ViewModel.Services.IWindowService)(New Services.WindowService())

      Dieser Code fügt eine neue Instanz des WindowService vom Type IWindowService dem ServiceContainer hinzu damit wir im ViewModel nun jederzeit mit Fenstern "hantieren" können ohne etwas über ein Fenster oder dessen Funktionalität zu kennen.


      So das wars dann auch.

      Hier das Template für das "Minimal MVVM":
      MVVM_Template.zip

      Hier das "angereicherte" Template:
      MVVM_Template.zip

      Ich wünsche euch einen schönen Tag und Happy Coding
      Grüße
      Sascha
      If _work = worktype.hard Then Me.Drink(Coffee)
      Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

      ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

      Hallo,

      erstmal vielen Dank für das Template - super Arbeit.
      Mir kommt es irgendwie bekannt vor, kann es sein, dass du so etwas schon mal gemacht hast...?

      Zumindest sind hier alle wichtigen Projektschichten enthalten, was sehr gut ist, denn das Verweise setzen ist - wie du sagst - immer sehr anstrengend.

      Ich werde das Template auch mal auf C# umschreiben und hier veröffentlichen - natürlich nur wenn es für dich ok ist - vielleicht hat davon auch jemand etwas.

      Jetzt hätte ich aber noch ein paar kleine Anregungen:

      1. Mir fehlt in deiner Projektvorlage klar die ​WindowExtention Klasse - die ist super, und die braucht man eigentlich auch, wenn man richtig MVVM macht...

      2. Ich fände es schön - da du schon eine Service Klasse intigrierst - wenn es noch ein paar essenzielle mehr gäbe (denn gelöscht sind sie schnell und stören tun sie auch nicht groß... - das Erstellen ist aber immer sehr nervig). Damit meine ich hauptsächlich: ​IDialogWindowService, ​IMessageBoxService, ​IOpen(Save)FileDialogService

      2. Eventuell wäre mal eine "Ultra" Vorlage eine Idee - wo auch noch die Projekte BusinessLogic und (eventuell DBContext) enthalten sind.

      Trotzdem aber eine super Vorlage!

      Viele Grüße
      Florian
      Meine Website
      Mein Projekt: SnippetLibrary
      Hi,
      stimme da @florian03 zu, super Arbeit @Nofear23m.
      Ich hatte mich auch mal an einem Template versucht, denn die ganze kopierererei aus abgeschloßenen Projekten nervt echt, bin aber zu blöd dafür...
      Hab zwar inzwischen meine eignenen nuget Pakete auf AzureDevOps für die ganzen Basisklassen, aber auch hier muss ich immer wieder alle Verweise setzen.

      Ein C# Template (auch Ultra) wäre echt toll. Alternativ vielleicht ein Video, wo Du zeigst, wie man soclh ein Template aufsetzt (nur wenn Du Zeit hast natürlich)....
      "Hier könnte Ihre Werbung stehen..."
      Naja, so ein Template ist schon irgendwie eine frikelei. Aber brauchst dir nur das Templatefile in einem Editor aufmachen, da siehst du wie das funktioniert.
      Achtung: Die .Net Core Template sehen wieder völlig anders aus und funktionieren auch komplett verschieden soweit ich weis.

      Ich habe absichtlich keine Eierlegene Wollmilchsau erstellt weil gerade die "Services" sind eine Sache wo jeder was anderes benötigt. Aber jeder kann ja funktionalitäten mit reinholen.
      @florian03 Ja, die WindowExtension ist sehr praktisch aber auch hier gilt. Einfach das File reinkopieren und man hat die Funktionalität. Ich bin/war der Meinung das dies nicht ins Template rein muss da jeder hier vermutlich was anderes verwendet, auch meine Klassen, Services und Extension sind sicherlich nicht perfekt und dann muss jeder erst wieder alles löschen was er nicht braucht. Ja, gelöscht ist schnell, reinkopiert aber auch :huh:

      Grüße
      Sascha
      If _work = worktype.hard Then Me.Drink(Coffee)
      Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

      ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

      MichaHo schrieb:

      Alternativ vielleicht ein Video, wo Du zeigst, wie man soclh ein Template aufsetzt (nur wenn Du Zeit hast natürlich)...



      Fände ich auch sehr interessant - es muss ja keineswegs ins Detail gehen.
      Du könntest z.B. einfach nur kurz zeigen wie man anfängt, und am Ende "richtig Exportiert".
      Sodass zum Beispiel das Framework nur für bestimmte Bereiche eingestellt werden kann, oder dass sich der entgültige Projektname der Eizelprojekte immer an dem Namen des ganzen Projekts orientiert....

      Viele Grüße
      Florian
      Meine Website
      Mein Projekt: SnippetLibrary
      OK, vieleicht finde ich am Wochenende mal Zeit. Das ist schon wieder sooo lange her das ich das Template erstellt habe das ich mich da selbst erstmal wieder einlesen muss :P

      Mal sehen, vieleicht überrasche ich euch ja. *gg*

      Grüße
      Sascha
      If _work = worktype.hard Then Me.Drink(Coffee)
      Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

      ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

      Hi,
      hab heute Morgen auch ein MVVM Template in C# erstellt.
      Ging eigentlich ganz einfach, ist halt nur viel Fummelei mit den ganzen Verweisen und in den einzelnen Klassen sind ja teilweise auch verweise drin.

      z.Bsp. Im Context, muss ja der InstanceHolder und das Model importiert werden:

      C#-Quellcode

      1. using Inventory.InstanceHolder;
      2. using Inventory.Model;


      diese ganzen Verweise muss man auch in den Dateien im Template selbst mit

      C#-Quellcode

      1. using $ext_safeprojectname$.InstanceHolder;
      2. using $ext_safeprojectname$.Model;

      anpassen, sonst gibts Fehler.

      Eine Sache hab ich leider noch nicht hin bekommen.
      Ich verwalte gerne die Solution in Ordnern, also innerhalb der Solution hab ich SolutionFolder für Application, BusinessLogic usw.
      Die SolutionFolder anzulegen ist nicht das Problem, allerdings habe ich innerhalb der Solution Mappe auf der Festplatte die gleiche Ordnerstruktur immer angelegt (siehe Bildchen).
      Das gelingt mir leider nicht, die Folder auch auf die Platte anzulegen über das Template.
      Hab bei Tante Google gefragt, aber nichts dazu gefunden, nur grundsätzlich wie man SolutionFolder anlegt, aber das klappt ja.



      Vielleicht habt Ihr noch eine Idee dazu. Ansonsten bleibt es halt so...
      "Hier könnte Ihre Werbung stehen..."
      Ich weis es nicht mehr genau aber ich glaube das die Ordnerstruktur von Dateisystem so übernommen wird wie die Files gepackt werden oder?
      Du musst dann nur die Dateiverweise im Template anpassen.

      Grüße
      Sascha
      If _work = worktype.hard Then Me.Drink(Coffee)
      Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

      ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

      MichaHo schrieb:

      ich müsste, bevor ich alles komplett zu einem Zip packe, die Ordnerstruktur anlegen?

      Jep, denke das diese Struktur so übernommen wird. Kann mich aber irren.

      Grüße
      Sascha
      If _work = worktype.hard Then Me.Drink(Coffee)
      Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

      ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

      MichaHo schrieb:

      Naja egal, mit dem Template sind ja schon mal einige Stunden an kopiererei weg.

      Richtig, das ist/war ja das Ziel. Übrigend können auf diese art und weise nicht nur ProjektTemplates erstellt werden sondern auch die FileTemplates. Also die, die man mit "Element hinzufügen" einem Projekt hinzufügen kann.
      Das kann auch sehr praktisch sein um seine "standard" dinge abzudecken.

      Grüße
      Sascha
      If _work = worktype.hard Then Me.Drink(Coffee)
      Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

      ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

      Ja, das mit den ItemTemplate kenn ich schon und hab ich auch schon genutzt.

      Falls jemand das C# Template haben möchte, kann ich es gerne zur Verfügung stellen. Die Struktur ist ähnlich die von @Nofear23m
      "Hier könnte Ihre Werbung stehen..."
      Hallo,

      wenn du mir das Template zur Verfügung stellen könntest wäre das sehr nett - kann ich mir Mal anschauen, wie es andere machen :)

      Viele Grüße
      Florian
      Meine Website
      Mein Projekt: SnippetLibrary

      Neu

      @florian03 sorry, war am Wochenende viel unterwegs.
      Hier nun das Template. Zu finden dann im Visual Studio unter "MHoApps MVVM Solution Template"
      Kannst Du aber natürlich auch abändern...
      Dateien
      • MVVM_Template.zip

        (137,56 kB, 7 mal heruntergeladen, zuletzt: )
      "Hier könnte Ihre Werbung stehen..."

      Neu

      Hallo @MichaHo

      vielen Dank für das Template!

      Musstest du die ​.vstemplate Dateien selbst erstellen oder macht das VS mit all den Einstellungen (dass sich der Name übernimmt) selbst?

      Viele Grüße
      Florian
      Meine Website
      Mein Projekt: SnippetLibrary

      Neu

      Ich wurde auch nicht schlau draus, hab mir dann aber das Template von @Nofear23m Angeschaut, dann meine Template auf dem 2, Bildschirm, mehrfach importiert und geschaut und dann viel der Groschen.
      "Hier könnte Ihre Werbung stehen..."

      Neu

      Ich hatte auch alles aus der MS Doku. Ja, die ist nicht gut, aber die XML sond recht logisch aufgebaut.
      If _work = worktype.hard Then Me.Drink(Coffee)
      Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

      ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##