Erstellen von plattformübergreifenden Apps mit Xamarin: Perspektive eines Android-Entwicklers

Veröffentlicht: 2022-03-11

Code einmal zu schreiben und ihn auf mehreren Plattformen zu verwenden, war ein Traum vieler Softwareentwickler. Obwohl dies schon seit einiger Zeit möglich ist, ging dies immer auf Kosten der Wartbarkeit, der Testfreundlichkeit oder, noch schlimmer, einer schlechten Benutzererfahrung.

Die Entwicklung mobiler Anwendungen mit dem nativen SDK ist wahrscheinlich der Ausgangspunkt für alle Entwickler, die ihre Wurzeln im Bereich der Entwicklung von Desktop-Anwendungen haben. Programmiersprachen würden für einige zu einem Hindernis werden: Wenn jemand Erfahrung in der Entwicklung von Java-Desktop- oder Backend-Anwendungen hätte, würde es sich viel einfacher anfühlen, zu einer Firma für die Entwicklung mobiler Apps zu wechseln und mit Android zu arbeiten, als mit Objective-C für iOS von Grund auf neu zu beginnen.

Ich war immer skeptisch gegenüber der plattformübergreifenden Anwendungsentwicklung. JavaScript-basierte Frameworks wie Sencha, Cordova, Titanium usw. erweisen sich nie als eine kluge Wahl, wenn Leistung wichtig ist. Das Fehlen von APIs und eine skurrile Benutzererfahrung waren bei diesen Frameworks eine Selbstverständlichkeit.

Aber dann stieß ich auf Xamarin.

Plattformübergreifende Entwicklung mit Xamarin

In diesem Artikel erfahren Sie, wie Sie mit Xamarin Code über mehrere Plattformen hinweg freigeben können, ohne die anderen Aspekte der Entwicklung mobiler Anwendungen zu beeinträchtigen. Der Artikel konzentriert sich insbesondere auf Android und iOS, aber Sie können einen ähnlichen Ansatz verwenden, um Unterstützung für jede andere von Xamarin unterstützte Plattform hinzuzufügen.

Was ist Xamarin?

Xamarin ist eine Entwicklungsplattform, mit der Sie plattformübergreifende – aber native – Anwendungen für iOS, Android und Windows Phone in C# und .NET schreiben können.

Xamarin stellt C#-Bindungen für native Android- und iOS-APIs bereit. Dies gibt Ihnen die Möglichkeit, die gesamte native Benutzeroberfläche, Benachrichtigungen, Grafiken, Animationen und andere Telefonfunktionen von Android und iOS zu verwenden – alles mit C#.

Jede neue Version von Android und iOS wird von Xamarin mit einer neuen Version abgeglichen, die Bindungen für ihre neuen APIs enthält.

Der .NET-Port von Xamarin umfasst Funktionen wie Datentypen, Generika, Garbage Collection, sprachintegrierte Abfragen (LINQ), asynchrone Programmiermuster, Delegaten und eine Teilmenge von Windows Communication Foundation (WCF). Bibliotheken werden so verwaltet, dass sie nur die referenzierten Komponenten enthalten.

Xamarin.Forms ist eine Ebene über den anderen UI-Bindungen und der Windows Phone-API, die eine vollständig plattformübergreifende Benutzeroberflächenbibliothek bereitstellt.

Der Umfang von Xamarin

Plattformübergreifende Anwendungen schreiben

Um plattformübergreifende Anwendungen mit Xamarin zu schreiben, müssen Entwickler einen der beiden verfügbaren Projekttypen auswählen:

  • Portable Klassenbibliothek (PCL)
  • Gemeinsames Projekt

Mit der PCL können Sie Code schreiben, der von mehreren Plattformen gemeinsam genutzt werden kann, jedoch mit einer Einschränkung. Da nicht alle .NET-APIs auf allen Plattformen verfügbar sind, beschränken Sie ein PCL-Projekt auf die Ausführung auf Plattformen, für die es bestimmt ist.

Verbindungen und Einschränkungen von Xamarin

Die folgende Tabelle zeigt, welche APIs auf welchen Plattformen verfügbar sind:

Feature .NET-Framework Windows Store-Apps Silberlicht Windows Phone Xamarin
Kern Y Y Y Y Y
LINQ Y Y Y Y Y
IQueryable Y Y Y 7,5+ Y
Serialisierung Y Y Y Y Y
Datenanmerkungen 4.0.3+ Y Y Y Y

Während des Erstellungsprozesses wird eine PCL in separate DLLs kompiliert und während der Laufzeit von Mono geladen. Zur Laufzeit kann eine andere Implementierung derselben Schnittstelle bereitgestellt werden.

Auf der anderen Seite geben Ihnen freigegebene Projekte mehr Kontrolle, da Sie plattformspezifischen Code für jede Plattform schreiben können, die Sie unterstützen möchten. Der Code in einem gemeinsam genutzten Projekt kann Compilerdirektiven enthalten, die Codeabschnitte aktivieren oder deaktivieren, je nachdem, welches Anwendungsprojekt den Code verwendet.

Im Gegensatz zu einer PCL erzeugt ein freigegebenes Projekt keine DLL. Der Code wird direkt in das finale Projekt eingebunden.

Strukturieren Sie Ihren plattformübergreifenden Code mit MvvmCross

Wiederverwendbarer Code kann Entwicklungsteams Geld und Zeit sparen. Gut strukturierter Code erleichtert Entwicklern jedoch das Leben erheblich. Niemand schätzt gut geschriebenen, fehlerfreien Code mehr als Entwickler.

Xamarin selbst bietet einen Mechanismus, der das Schreiben von wiederverwendbarem plattformübergreifendem Code viel einfacher macht.

Mobile Entwickler sind mit Szenarien vertraut, in denen sie dieselbe Logik zweimal oder öfter schreiben müssen, um iOS, Android und andere Plattformen zu unterstützen. Aber mit Xamarin ist es, wie im vorherigen Kapitel erklärt, einfach, Code, der für eine Plattform geschrieben wurde, auch für einige andere Plattformen wiederzuverwenden.

Wo kommt dann MvvmCross ins Spiel?

MvvmCross ermöglicht, wie der Name schon andeutet, die Verwendung des MVVM-Musters in Xamarin-Anwendungen. Es enthält eine Reihe von Bibliotheken, APIs und Dienstprogrammen, die bei der plattformübergreifenden Anwendungsentwicklung sehr praktisch sind.

MvvmCross kann die Menge an Boilerplate-Code, den Sie in jedem anderen Ansatz zur Anwendungsentwicklung geschrieben hätten (manchmal mehrere Male in verschiedenen Sprachen), erheblich reduzieren.

Struktur einer MvvmCross-Lösung

Die MvvmCross-Community empfiehlt eine ziemlich einfache und effiziente Art, eine MvvmCross-Lösung zu strukturieren:

 <ProjectName>.Core <ProjectName>.UI.Droid <ProjectName>.UI.iOS

Das Kernprojekt in einer MvvmCross-Lösung bezieht sich auf wiederverwendbaren Code. Das Core-Projekt ist ein Xamarin-PCL-Projekt, bei dem der Hauptfokus auf der Wiederverwendbarkeit liegt.

Jeder in Core geschriebene Code sollte so weit wie möglich plattformunabhängig sein. Es sollte nur Logik enthalten, die auf allen Plattformen wiederverwendet werden kann. Das Core-Projekt darf weder Android- oder iOS-APIs verwenden noch auf plattformspezifische Elemente zugreifen.

Die Geschäftslogikschicht, die Datenschicht und die Back-End-Kommunikation sind allesamt perfekte Kandidaten für die Aufnahme in das Core-Projekt. Die Navigation durch die Hierarchie der Ansichten (Aktivitäten, Fragmente usw.) wird im Kern erreicht.

Bevor Sie fortfahren, ist es notwendig, ein architektonisches Entwurfsmuster zu verstehen, das für das Verständnis von MvvmCross und seiner Funktionsweise entscheidend ist. Wie der Name schon sagt, hängt MvvmCross stark vom MVVM-Pattern ab.

MVVM ist ein architektonisches Entwurfsmuster, das die Trennung der grafischen Benutzeroberfläche von der Geschäftslogik und den Back-End-Daten erleichtert.

Wie wird dieses Muster in MvvmCross verwendet?

Nun, da wir eine hohe Wiederverwendbarkeit unseres Codes erreichen möchten, möchten wir so viel wie möglich in unserem Kern haben, der ein PCL-Projekt ist. Da Ansichten der einzige Teil des Codes sind, der sich von einer Plattform zur anderen unterscheidet, können wir sie nicht plattformübergreifend wiederverwenden. Dieser Teil wird in den Projekten im Zusammenhang mit der Plattform implementiert.

MvvmCross-Struktur

MvvmCross gibt uns die Möglichkeit, die Anwendungsnavigation vom Kern aus mithilfe von ViewModels zu orchestrieren.

Nachdem die Grundlagen und technischen Details geklärt sind, beginnen wir mit Xamarin, indem wir unser eigenes MvvmCross Core-Projekt erstellen:

Erstellen eines MvvmCross Core-Projekts

Öffnen Sie Xamarin Studio und erstellen Sie eine Lösung namens ToptalExampleSolution :

Erstellen der Lösung

Da wir ein Kernprojekt erstellen, ist es eine gute Idee, sich an die Namenskonvention zu halten. Stellen Sie sicher, dass das Core Suffix zum Projektnamen hinzugefügt wird.

Um MvvmCross-Unterstützung zu erhalten, ist es erforderlich, unserem Projekt MvvmCross-Bibliotheken hinzuzufügen. Um hinzuzufügen, dass wir die integrierte Unterstützung für NuGet in Xamarin Studio verwenden können.

Um eine Bibliothek hinzuzufügen, klicken Sie mit der rechten Maustaste auf den Ordner Pakete und wählen Sie die Option Pakete hinzufügen .

Im Suchfeld können wir nach MvvmCross suchen, wodurch Ergebnisse im Zusammenhang mit MvvmCross wie unten gezeigt herausgefiltert werden:

Ergebnisse filtern

Durch Klicken auf die Schaltfläche Paket hinzufügen wird es dem Projekt hinzugefügt.

Nachdem MvvmCross zu unserem Projekt hinzugefügt wurde, sind wir bereit, unseren Kerncode zu schreiben.

Lassen Sie uns unser erstes ViewModel definieren. Um einen zu erstellen, erstellen Sie eine Ordnerhierarchie wie folgt:

Empfohlene Ordnerhierarchie

Hier ist, worum es in jedem der Ordner geht:

  • Modelle: Domänenmodelle, die reale Zustandsinhalte darstellen
  • Dienste: Ein Ordner, der unseren Dienst enthält (Geschäftslogik, Datenbank usw.)
  • ViewModel: Die Art und Weise, wie wir mit unseren Modellen kommunizieren

Unser erstes ViewModel heißt FirstViewModel.cs

 public class FirstViewModel : MvxViewModel { private string _firstName; private string _lastName; private string _fullName; public string FirstName { get { return _firstName; } set { _lastName = value; RaisePropertyChanged(); } } public string LastName { get { return _lastName; } set { _lastName = value; RaisePropertyChanged(); } } public string FullName { get { return _fullName; } set { _fullName = value; RaisePropertyChanged(); } } public IMvxCommand ConcatNameCommand { get { return new MvxCommand(() => { FullName = $"{FirstName} {LastName}"; }); } public IMvxCommand NavigateToSecondViewModelCommand { get { return new MvxCommand(() => { ShowViewModel<SecondViewModel>(); }); } } }

Jetzt, da wir unser erstes ViewModel haben, können wir unsere erste Ansicht erstellen und Dinge miteinander verbinden.

Android-Benutzeroberfläche

Um den Inhalt des ViewModel anzuzeigen, müssen wir eine Benutzeroberfläche erstellen.

Der erste Schritt zum Erstellen einer Android-Benutzeroberfläche besteht darin, ein Android-Projekt in der aktuellen Lösung zu erstellen. Klicken Sie dazu mit der rechten Maustaste auf den Lösungsnamen und wählen Sie Hinzufügen -> Neues Projekt hinzufügen… . Wählen Sie im Assistenten die Android-App aus und vergewissern Sie sich, dass Sie Ihr Projekt ToptalExample.UI.Droid .

Wie zuvor beschrieben, müssen wir nun MvvmCross-Abhängigkeiten für Android hinzufügen. Führen Sie dazu die gleichen Schritte wie für das Kernprojekt zum Hinzufügen von NuGet-Abhängigkeiten aus.

Nach dem Hinzufügen von MvvmCross-Abhängigkeiten ist es erforderlich, einen Verweis auf unser Core-Projekt hinzuzufügen, damit wir unseren dort geschriebenen Code verwenden können. Um einen Verweis auf das PCL-Projekt hinzuzufügen, klicken Sie mit der rechten Maustaste auf den Ordner „Referenzen“ und wählen Sie die Option „Referenzen bearbeiten… “. Wählen Sie auf der Registerkarte Projekte das zuvor erstellte Kernprojekt aus und klicken Sie auf OK.

Hinzufügen eines Verweises auf das PCL-Projekt

Der nächste Teil kann etwas schwierig zu verstehen sein.

Jetzt müssen wir MvvmCross mitteilen, wie es unsere Anwendung einrichten soll. Dazu müssen wir eine Setup -Klasse erstellen:

 namespace ToptalExample.UI.Droid { public class Setup : MvxAndroidSetup { public Setup(Context context) : base(context) { } protected override IMvxApplication CreateApp() { return new Core.App(); } } }

Wie aus der Klasse ersichtlich ist, teilen wir MvvmCross CreateApp mit, basierend auf der Core.App Implementierung, die eine in Core definierte und unten gezeigte Klasse ist:

 public class App : MvxApplication { public override void Initialize() { RegisterAppStart(new AppStart()); } } public class AppStart : MvxNavigatingObject, IMvxAppStart { public void Start(object hint = null) { ShowViewModel<FirstViewModel>(); } }

In der App -Klasse erstellen wir eine Instanz von AppStart , die unser erstes ViewModel zeigen wird.

Jetzt muss nur noch eine Android-Layout-Datei erstellt werden, die von MvvmCross gebunden wird:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro xmlns:local="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:layout_width="match_parent" android:layout_height="match_parent" local:MvxBind="Text FirstName" /> <EditText android:layout_width="match_parent" android:layout_height="match_parent" local:MvxBind="Text LastName" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" local:MvxBind="Text FullName" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" local:MvxBind="Click ConcatNameCommand" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" local:MvxBind="Click NavigateToSecondViewModelCommand" /> </LinearLayout>

In der Layoutdatei haben wir Bindungen, die automatisch von MvvmCross aufgelöst werden. Für EditText wir eine Bindung für die Eigenschaft Text, die eine bidirektionale Bindung sein wird. Jede Änderung, die von der ViewModel-Seite aufgerufen wird, wird automatisch in der Ansicht widergespiegelt und umgekehrt.

Die View -Klasse kann eine Aktivität oder ein Fragment sein. Der Einfachheit halber verwenden wir eine Aktivität, die das angegebene Layout lädt:

 [Activity(Label = "ToptalExample.UI.Droid", Theme = "@style/Theme.AppCompat", MainLauncher = true, Icon = "@mipmap/icon")] public class MainActivity : MvxAppCompatActivity<FirstViewModel> { protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); SetContentView(Resource.Layout.Main); } }

Für die erste Schaltfläche haben wir eine Befehlsbindung, was bedeutet, dass MvvmCross beim Klicken auf die Schaltfläche ContactNameCommand aus dem ViewModel aufruft.

Für die zweite Schaltfläche zeigen wir ein weiteres ViewModel.

iOS-Benutzeroberfläche

Das Erstellen eines iOS-Projekts unterscheidet sich nicht wirklich vom Erstellen eines Android-Projekts. Sie müssen ähnliche Schritte zum Hinzufügen eines neuen Projekts ausführen, nur erstellen Sie diesmal anstelle von Android einfach ein iOS-Projekt. Stellen Sie nur sicher, dass Sie die Namenskonvention konsistent halten.

Nachdem Sie das iOS-Projekt hinzugefügt haben, müssen Sie Abhängigkeiten für MvvmCross iOS hinzufügen. Die Schritte sind absolut dieselben wie für Core und Android (klicken Sie mit der rechten Maustaste auf Referenzen in Ihrem iOS-Projekt und klicken Sie auf Referenzen hinzufügen… ).

Jetzt ist es, wie wir es für Android getan haben, erforderlich, eine Setup -Klasse zu erstellen, die MvvmCross mitteilt, wie unsere Anwendung eingerichtet werden soll.

 public class Setup : MvxIosSetup { public Setup(MvxApplicationDelegate appDelegate, IMvxIosViewPresenter presenter) : base(appDelegate, presenter) { } protected override MvvmCross.Core.ViewModels.IMvxApplication CreateApp() { return new App(); } }

Beachten Sie, dass die Klasse Setup jetzt MvxIosSetup erweitert und für Android MvxAndroidSetup erweitert hat.

Eine Ergänzung hier ist, dass wir unsere AppDelegate -Klasse ändern müssen.

AppDelegate auf iOS ist für den Start der Benutzeroberfläche verantwortlich, daher müssen wir angeben, wie die Ansichten auf iOS dargestellt werden. Hier erfahren Sie mehr über Moderatoren.

 [Register("AppDelegate")] public class AppDelegate : MvxApplicationDelegate { // class-level declarations public override UIWindow Window { get; set; } public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) { Window = new UIWindow(UIScreen.MainScreen.Bounds); var presenter = new MvxIosViewPresenter(this, Window); var setup = new Setup(this, presenter); setup.Initialize(); var startup = Mvx.Resolve<IMvxAppStart>(); startup.Start(); Window.MakeKeyAndVisible(); return true; } }

Um unser ViewModel zu präsentieren, müssen wir eine Ansicht erstellen. Lassen Sie uns für diesen Fall einen ViewController erstellen, indem Sie mit der rechten Maustaste auf das Projekt klicken und Hinzufügen -> Neue Datei auswählen und ViewController aus dem iOS-Abschnitt auswählen, den wir FirstViewController nennen werden.

Xamarin erstellt drei Dateien, in denen wir definieren, wie unsere Bindungen aussehen werden. Im Gegensatz zu Android müssen wir für iOS unsere Bindungen auf andere Weise durch Code definieren (obwohl wir das auch auf Android tun können und dies in einigen Fällen erforderlich ist).

Wenn zwischen Ansichten navigiert werden muss, erfolgt dies über das ViewModel. Im Befehl NavigateToSecondViewModelCommand findet die Methode ShowViewModel<SecondViewModel>() die entsprechende Ansicht und navigiert dorthin.

Aber woher weiß MVVMCross, welche Ansicht geladen werden soll?

Darin liegt keine Magie. Wenn wir eine Ansicht für Android (Aktivität oder Fragment) erstellen, erweitern wir eine der Basisklassen mit Typparametern ( MvxAppCompatActivity<VM> ). Wenn wir ShowViewMolel<VM> aufrufen, sucht MvvmCross nach einer View , die die Activity oder Fragment -Klasse mit den Typparametern VM erweitert. Aus diesem Grund dürfen Sie nicht zwei Ansichtsklassen für dasselbe ViewModel haben.

Umkehrung der Kontrolle

Da Xamarin lediglich C#-Wrapper um native APIs herum bereitstellt, bietet es keine Form von Dependency Injection (DI) oder Inversion of Control (IoC)-Mechanismus.

Ohne Laufzeitinjektion von Abhängigkeiten oder Kompilierungszeitinjektion ist es nicht einfach, lose gekoppelte, wiederverwendbare, testbare und leicht wartbare Komponenten zu erstellen. Die Idee von IoC und DI ist schon sehr lange bekannt; Einzelheiten zu IoC finden Sie in vielen Artikeln online. Mehr über diese Muster erfahren Sie im Einführungsartikel von Martin Fowler.

IoC ist seit frühen Versionen von MvvmCrosses verfügbar und ermöglicht das Einfügen von Abhängigkeiten zur Laufzeit, wenn die Anwendung startet und wann immer sie benötigt werden.

Um lose gekoppelte Komponenten zu erhalten, sollten wir niemals konkrete Implementierungen von Klassen fordern. Das Erfordernis konkreter Implementierungen schränkt die Möglichkeit ein, das Verhalten der Implementierungen während der Laufzeit zu ändern (Sie können es nicht durch eine andere Implementierung ersetzen). Das macht es schwierig, diese Komponenten zu testen.

Aus diesem Grund werden wir eine Schnittstelle deklarieren, für die wir eine konkrete Implementierung haben werden.

 public interface IPasswordGeneratorService { string Generate(int length); }

Und Umsetzung:

 public class PasswordGeneratorService : IPasswordGeneratorService { public string Generate(int length) { var val; var res = new StringBuilder(); var rnd = new Random(); while (0 < length--) { res.Append(valid[rnd.Next(valid.Length)]); } return res.ToString(); } }

Unser ViewModel kann nun eine Instanz der Schnittstelle IPasswordGenerationService , für deren Bereitstellung wir verantwortlich sind.

Damit MvvmCross zur Laufzeit eine PasswordGeneratorService -Implementierung einfügen kann, müssen wir MvvmCross mitteilen, welche Implementierung verwendet werden soll. Wenn wir eine Implementierung für beide Plattformen verwenden möchten, können wir die Implementierungen nach der Anwendungsregistrierung in App.cs registrieren:

 public override void Initialize() { RegisterAppStart(new AppStart()); Mvx.LazyConstructAndRegisterSingleton<IPasswordGeneratorService, PasswordGeneratorService>(); }

Der obige Aufruf der statischen Methode LazyConstructAndRegisterSingleton<TInterface, TType> registriert die einzufügende Implementierung. Diese Methode registriert die entsprechende Implementierung, erstellt jedoch kein Objekt.

Das Objekt wird nur erstellt, wenn es erforderlich ist, und nur einmal, da es als Singleton registriert ist.

Wenn wir sofort ein Singleton-Objekt erstellen möchten, kann dies durch Aufrufen von Mvx.RegisterSingleton<TInterface>() erreicht werden.

Es gibt Fälle, in denen wir nicht nur Singletons in unserer Anwendung haben möchten. Unser Objekt ist möglicherweise nicht Thread-sicher oder es gibt einen anderen Grund, warum wir immer eine neue Instanz haben möchten. Wenn dies der Fall ist, stellt MvvmCross die Methode Mvx.RegisterType<TInterface,TType>() mit der die Implementierung so registriert werden kann, dass bei Bedarf eine neue Instanz instanziiert wird.

Falls Sie für jede Plattform separate konkrete Implementierungen bereitstellen müssen, können Sie dies jederzeit in den plattformspezifischen Projekten tun:

 public class DroidPasswodGeneratorService : IPasswordGeneratorService { public string Generate(int length) { return "DroidPasswordGenerator"; } }

Und die Registrierung unserer Implementierung erfolgt in der Setup.cs -Klasse unter dem Droid-Projekt:

 protected override void InitializePlatformServices() { base.InitializePlatformServices(); Mvx.LazyConstructAndRegisterSingleton<IPasswordGeneratorService, DroidPasswodGeneratorService>(); }

Nach der Initialisierung des PCL-Codes ruft MvvmCross InitializePlatformServices auf und registriert unsere plattformspezifischen Dienstimplementierungen.

Wenn wir mehrere Singleton-Implementierungen registrieren, verwendet MvvmCross nur die zuletzt registrierte Implementierung. Alle anderen Anmeldungen werden verworfen.

Erstellen Sie plattformübergreifende Apps mit Xamarin

In diesem Artikel haben Sie gesehen, wie Sie mit Xamarin Code über verschiedene Plattformen hinweg gemeinsam nutzen und dennoch das native Gefühl und die Leistung der Anwendungen beibehalten können.

MvvmCross bietet eine weitere Abstraktionsebene, die die Erfahrung beim Erstellen plattformübergreifender Anwendungen mit Xamarin weiter verbessert. Das MVVM-Muster bietet eine Möglichkeit, Navigations- und Benutzerinteraktionsabläufe zu erstellen, die für alle Plattformen gleich sind, wodurch die Menge an plattformspezifischem Code, die Sie schreiben müssen, auf Ansichten beschränkt ist.

Ich hoffe, dieser Artikel hat Ihnen einen Grund gegeben, einen Blick auf Xamarin zu werfen, und Sie motiviert, Ihre nächste plattformübergreifende Anwendung damit zu erstellen.