Dieser Artikel wurde maschinell übersetzt.
Windows Phone
Erstellen von MVVM-Apps mithilfe von Xamarin und MvvmCross
Das Model-View-ViewModel (MVVM) Muster steht das Referenzmuster Wahl für jede XAML (Windows Presentation Foundation [WPF], Windows 8, Windows Phone und Silverlight) Anwendung geworden. Anfang von WPF vorgestellt, trennt es Bedenken, Testbarkeit und vieles mehr. Der beste Teil ist, dass Sie es für andere Technologien, auch diejenigen, die XAML nicht verwenden können. Tatsächlich können Sie das Muster mit ASP.NETmit JavaScript und vieles mehr.
Xamarin können Sie Android oder iOS-Anwendungen in C#-Code zu entwickeln. Diese Anwendungen verfügen über eigene Entwicklungsmodelle, aber dank eines Rahmens, genannt MvvmCross, bringen Sie das MVVM-Muster auf diese Plattformen auch. In diesem Artikel gebe ich dir alle, die du verstehen MvvmCross und wie musst man es in den Android- und iOS-Anwendungen verwenden.
Ein kurzer Blick auf MVVM
Gab es eine Menge Artikel über MVVM in letzter Zeit, so verbringe ich viel Zeit, die Überprüfen des MVVM-Musters wird nicht. Zusammenfassend besteht MVVM aus drei Teilen: Das Modell (entspricht die Daten, die Sie möchten anzeigen und bearbeiten am Bildschirm), die Ansicht (die die Präsentation-Komponente und die Benutzeroberfläche ist) und das ViewModel (die dauert des Modells auf die Ansicht mithilfe von Datenbindung anzeigen und wird auf Benutzerinteraktionen reagieren). Abbildung 1 zeigt eine grafische Darstellung des MVVM.
Abbildung 1 Übersicht über das Model-View-ViewModel-Muster
Wenn Sie mit Microsoft-Technologien zu entwickeln, ist es leicht zu sehen, die Wiederverwendbarkeit von MVVM bereitgestellt. Aber was ist mit nicht-Microsoft-Technologien? Was ist mit Android? Was ist mit iOS?
Of course, you can still implement your own patterns or methodologies, but those might not provide some of the Natürlich können Sie noch eigene Muster oder Methoden implementieren, aber die bieten einige der mächtigsten Funktionen von MVVM, z. B. Datenbindung und Testbarkeit möglicherweise nicht. Einer der größten Vorteile der folgenden MVVM ist die ViewModels sind leicht getestet werden. Dies können Sie Cross-Plattform-Code in der ViewModel zu drängen. Dieser Code würde sonst enthalten sein, in einem Plattform -bestimmte Klasse, wie ein Controller.
Xamarin und MvvmCross "lösen" das und bieten eine einheitliche Möglichkeit, MVVM auf anderen Plattformen zu verwenden. Vor der Suche mit MVVM auf anderen Plattformen, nehme ich einen Moment Xamarin zu erklären.
Xamarin für Android/iOS-Anwendungen
Xamarin ist eine Reihe von Tools, die Hochleistungs-kompilierten Code mit vollem Zugriff zu den systemeigenen APIs liefert. Es ermöglicht die Erstellung von nativen Anwendungen mit gerätespezifischen Erfahrungen. Alles, was Sie, in Objective-C oder Java, können Sie in c# mit Xamarin tun.
Während Sie Xamarin Studio entwickeln Anwendungen verwenden können, können Sie auch Visual Studio und alle anderen Werkzeuge, die Sie bereits für C#-Entwicklung heute verwenden. Dazu gehören Team Foundation Server (für die Quellcodeverwaltung) und Plug-ins wie Resharper, GhostDoc und so weiter.
Aus der Perspektive eines Entwicklers, Xamarin bietet drei Haupt-products—Xamarin.Mac, Xamarin.iOS (MonoTouch.dll) und Xamarin.Android (Mono.Android.dll). Alle diese Siedlungsfläche auf Mono, die open-Source-Version von der Microsoft .NET Framework. Mono war eigentlich zunächst von Miguel De Icaza, der Mitbegründer und CTO der aktuellen Xamarin erstellt.
In iOS kompiliert ein dedizierter Compiler direkt in systemeigenen Code in ARM zu c# geschriebene Anwendungen. Für Android ähnelt der Prozess .NET Kompilierung und Ausführung. Der Sourcecode wird in einen intermediate Language (IL) kompiliert. Wenn der Code auf dem Gerät ausgeführt wird, wird eine zweite Compilation (durchgeführt Just-in-Time) den IL-Code in systemeigenen Code kompiliert. Dies ist sinnvoll, da Android-Anwendungen in Javaentwickelt worden sind, hat eine interne Architektur die Architektur des .NET Framework ähnlich. Kann man eine visuelle Darstellung des Kompilierungsvorgangs für iOS und Android in Abbildung 2.
Abbildung 2 Native Kompilierung mit Xamarin
Die meiste Zeit, musst du die Speicherverwaltung, Zuweisung von Ressourcen und so weiter kümmern, da alles von der Common Language Runtime verwaltet wird, bietet Xamarin. Aber gibt es Fälle, wenn Sie müssen wissen was geschieht, wie Interop mit Objective-C. Hierdurch konnte behalten Zyklen oder in verwaltete Klasse eigentlich einige teuren Ressourcen, z. B. UIImage auf iOS umbrochen wird. Weitere Informationen dazu finden Sie unter bit.ly/1iRCIa2.
Gibt es Besonderheiten bei der iOS-Anwendungen. Während Xamarin Studio auf einem Mac alles notwendige für iOS-Devel bietetwicklung, Visual Studio -Benutzer auf einem PC brauchen noch einen Mac Xamarin Tools installiert sind. Dies können Sie Anwendungen über das Netzwerk zu kompilieren und testen diese auf der iOS-Simulator oder ein iOS-Gerät.
Xamarin können Sie iOS und Android-Anwendungen mit C#- oder F-, aber das traditionelle Model-View-Controller-Muster zu erstellen. Wenn Sie erhöhte Testbarkeit, Wartbarkeit und Portabilität möchten, benötigen Sie eine Möglichkeit, das MVVM-Muster auf diese Plattformen zu bringen. Geben Sie MvvmCross ein.
MvvmCross für Xamarin Apps
MvvmCross ist ein quelloffenes, plattformübergreifendes MVVM Framework entwickelt von Stuart Lodge. Es ist verfügbar für Windows 8, Windows Phone, iOS, Android und WPF-Anwendungen. MvvmCross bringt das MVVM-Muster auf Plattformen, wo war es bisher nicht verfügbar, wie iOS und Android.
Es unterstützt auch die Datenbindung in Ansichten. Dies ist eine leistungsfähige Funktion, die große Trennung von Bereichen bereitstellt. Die Ansicht wird die ViewModels verwenden, um korrekte Verhaltensweisen in der Anwendung anzubieten. MvvmCross sucht die ViewModels sogar in einem speziellen Projekt, so können Sie leicht verweisen und diese in anderen wiederverwenden.
Dies ist der wichtigste Punkt, wenn es um MvvmCross geht. Durch Auffinden der ViewModels in eine Portable Klasse Bibliothek (PCL), können Sie sie als Verweis auf andere Projekte hinzufügen. Das ist natürlich nicht der einzig interessante Punkt MvvmCross. Es gibt auch eine Plugin-Architektur, Dependency Injection (DI) und mehr.
Mithilfe von MvvmCross auf Android/iOS
Von MvvmCross ist einfach, denn es ist nur ein paar NuGet Pakete, die Sie Ihren Projekten hinzufügen. Sobald Sie dies getan haben, gibt es ein paar kleine Schritte musst du nehmen, bevor Sie die Anwendung starten. Die Schritte variieren ein bisschen zwischen iOS und Android, aber sie sind ziemlich ähnlich. Das Core-Projekt enthält Ihre ViewModels und die App-Klasse. Dieser initialisiert die Dienste und definiert das ViewModel, der beim Start gestartet werden:
public class App : MvxApplication
{
public override void Initialize()
{
this.CreatableTypes()
.EndingWith("Service")
.AsInterfaces()
.RegisterAsLazySingleton();
this.RegisterAppStart<HomeViewModel>();
}
}
Der iOS oder Android Anwendung müssen Sie eine Setup.cs-Datei zu erstellen. Dies verweist das Kernprojekt und lassen Sie die Common Language Runtime, die wissen, wie man die Anwendung zu instanziieren:
public class Setup : MvxAndroidSetup
{
public Setup(Context applicationContext) : base(applicationContext)
{
}
protected override IMvxApplication CreateApp()
{
return new Core.App();
}
}
So bringt die Setup-Datei die Anwendung mithilfe der app-Datei. Letzteres zeigt die Common Language Runtime ein bestimmtes ViewModel beim Start mit der RegisterAppStart-Methode geladen werden.
Jede Ansicht ist spezifisch für jede Anwendung. Dies ist der einzige Teil, das ändert. Auf Android erbt die Klasse von MvxActivity (Standardaktivitäten auf Android von Aktivität erben). Für iOS erben die Ansichten von MvxViewController (Standard ViewController auf iOS vererben UIViewController):
[Activity(ScreenOrientation = ScreenOrientation.Portrait)]
public class HomeView : MvxActivity
{
protected override void OnViewModelSet()
{
SetContentView(Resource.Layout.HomeView);
}
}
MvvmCross muss das ViewModel kennen, der eine Ansicht zugeordnet ist. Dies ist dank der Namenskonvention standardmäßig möglich. Sie können auch leicht ändern, indem Sie überschreiben die ViewModel-Eigenschaft der Ansicht oder dem MvxViewForAttribute:
[Activity(ScreenOrientation = ScreenOrientation.Portrait)]
[MvxViewFor(typeof(HomeViewModel))]
public class HomeView : MvxActivity
{ ... }
Auf iOS und Android sind die Ansichten mit unterschiedlichen Herangehensweisen entwickelt. Auf iOS ist die Ansicht im C#-Code definiert. Auf Android können Sie auch C#-Code. Noch besser ist, allerdings können Sie das AXML-Format (XML-Format verwendet, um die Benutzeroberfläche auf Android zu beschreiben). Aufgrund dieser Unterschiede sind die Datenbindungen auf jeder Plattform unterschiedlich definiert.
Auf iOS erstellen Sie eine BindingDescriptionSet um die Verbindung zwischen der Ansicht und die ViewModel darzustellen. In diesem Satz geben Sie das Steuerelement, das Sie vor der Anwendung der Bindung welche Eigenschaft binden möchten:
var label = new UILabel(new RectangleF(10, 10, 300, 40));
Add(label);
var textField = new UITextField(new RectangleF(10, 50, 300, 40));
Add(textField);
var set = this.CreateBindingSet<HomeView,
Core.ViewModels.HomeViewModel>();
set.Bind(label).To(vm => vm.Hello);
set.Bind(textField).To(vm => vm.Hello);
set.Apply();
Das neue XML-Attribut MvxBind können Sie auf Android mit AXML die die Datenbindung durchzuführen:
<TextView xmlns:local="https://schemas.android.com/apk/res-auto"
android:text="Text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tripitem_title"
local:MvxBind="Text Name"
android:gravity="center_vertical"
android:textSize="17dp" />
Das MvxBind-Attribut nimmt in Parametern, die die Eigenschaft des Steuerelements binden und die Eigenschaft der ViewModel als Quelle verwenden angeben. Wenn Sie ein XAML-Entwickler sind, achten Sie darauf, dass der MvvmCross-Bindungsmodus TwoWay standardmäßig ist. In XAML ist der Standardmodus für die Bindung OneWay. MvvmCross Rahmen versteht einige benutzerdefinierte XML-Attribute verfügbar in MvxBindingAttributes.xml, wie Sie sehen Abbildung 3.
Abbildung 3 Inhalt der Datei MvxBindingAttributes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-stylable name="MvxBinding">
<attr name="MvxBind" format="string"/>
<attr name="MvxLang” format="string"/>
</declare-styleable>
<declare-stylable name="MvxControl">
<attr name="MvxTemplate" format="string"/>
</declare-styleable>
<declare-styleable name="MvxListView">
<attr name="MvxItemTemplate" format= "string"/>
<attr name="MvxDropDownItemTemplate" format="string"/>
</declare-stylable>
<item type="id" name="MvxBindingTagUnique">
<declare-styleable name="MvxImageView">
<attr name="MvxSource" format="string"/>
</declare-stylable>
</resources>
Der Inhalt dieser Datei ist einfach, aber sehr wichtig. Die Datei gibt die Attribute, die Sie in den AXML-Dateien verwenden können. Also, Sie sehen in einem Bindungsvorgang können Sie MvxBind oder MvxLang-Attribute verwenden. Sie können auch einige neue Steuerelemente (MvxImageView, MvxListView). Jeder von ihnen hat benutzerdefinierte Attribute gewidmet, wie Sie, in sehen können Abbildung 4.
Abbildung 4 neue Steuerelemente über benutzerdefinierte Attribute verfügen.
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="2">
<Mvx.MvxListView
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
local:MvxBind="ItemsSource Trips;ItemClick SelectTripCommand"
local:MvxItemTemplate="@layout/tripitemtemplate" />
</LinearLayout>
Dies sollte XAML-Entwicklern vertraut sein. Die ItemsSource und ItemClick-Eigenschaften sind auf bestimmte Eigenschaften der Datenquelle (in diesem Fall ViewModel) gebunden. Die MvxItemTemplate definiert die Schnittstelle für jedes Element in der ListView.
Sie erwarten die Syntax für iOS ganz anders aussehen, aber in Wirklichkeit ist es eigentlich ziemlich ähnlich. Die Syntax in der Datei AXML genannt "Fließend" Bindung, ist einfach eine Text-Format-Bindung, für die Sie die C#-Version auch zuordnen können. Im vorherigen Beispiel verwendet werden, um ein Element in der Liste auswählen des Befehls ist ein ICommand-Objekt:
public ICommand<Trip> SelectTripCommand { get; set; }
Die Implementierung dieser Schnittstelle wird von MvvmCross bereitgestellt, mithilfe der MvxCommand-Klasse:
private void InitializeCommands()
{
this.SelectTripCommand = new MvxCommand<Trip>(
trip => this.ShowViewModel<TripDetailsViewModel>(trip),
trip => this.Trips != null && this.Trips.Any() && trip != null);
}
Ein häufiges Problem, wenn Sie mit dem MVVM-Muster Typen konvertieren ist. Dies geschieht, wenn Sie Eigenschaften mit Hilfe einer Art, die direkt von der Benutzeroberfläche konsumierbare nicht definieren. Beispielsweise konnten Sie eine Image-Eigenschaft als Byte-Array, aber für die Source-Eigenschaft eines Bild-Steuerelements verwendet werden soll. In XAML können Sie dieses Problem mit der IValueConverter-Schnittstelle, lösen die Werte zwischen der Ansicht und die ViewModel abbildet.
Der Prozess ist sehr ähnlich mit MvvmCross, dank der IMvxValueConverter-Schnittstelle und den beiden Methoden Convert und ConvertBack. Mit dieser Schnittstelle können Sie ähnliche Konvertierungen durchführen XAML, sondern mit einem Kreuz-Technologie-Ziel vor Augen. Halten Sie im Verstand, diese Schnittstelle hat den gleichen Nachteil als XAML. Es nimmt ein Objekt als Parameter und gibt es als Wert. Casting ist also erforderlich. Um dies zu optimieren, bietet MvvmCross die generische MvxValueConverter-Klasse, die im Parameter für die Eingabe und die Rückgabetypen nimmt:
public class ByteArrayToImageConverter :
MvxValueConverter<byte[], Bitmap>
{
protected override Bitmap Convert(byte[] value, Type targetType,
object parameter, CultureInfo culture)
{
if (value == null)
return null;
var options = new BitmapFactory.Options { InPurgeable = true };
return BitmapFactory.DecodeByteArray(value,
0, value.Length, options);
}
}
Referenzierung des Konverters ist einfach. Verwenden Sie in iOS die Methode WithConversion in der fließend-Syntax:
var set = this.CreateBindingSet<HomeView,
Core.ViewModels.HomeViewModel>();
set.Bind(label).To(vm => vm.Trips).WithConversion("ByteArrayToImage");
set.Apply();
Verweisen Sie in Android den Konverter direkt in der Datei AXML:
<ImageView
local:MvxBind="Bitmap Image,Converter=ByteArrayToImage"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
Wandler befinden sich durch ihre Namen mithilfe von Reflektion. Standardmäßig sucht der Rahmen für jede Art "Converter" im Namen "enthalten. Sie können auch manuell Konverter registrieren, durch Überschreiben der FillValueConverters-Methode in der Setup-Klasse.
MvvmCross bietet eine einfache und leichte DIcontainer. Sie können Klassen und Schnittstellen in den Container mit mehrere Muster, darunter eine Singleton-Registrierung und eine dynamische Registrierung registrieren:
Mvx.RegisterType<ISQLiteConnectionFactory, SQLiteConnectionFactory>();
Mvx.RegisterSingletong<ISQLiteConnectionFactory, SQLiteConnectionFactory>();
Auflösen von Typen im Container kann zweierlei passieren. Zunächst können Sie die Mvx.Resolve-Methode explizit den Typ aufzulösen. Es unterstützt auch Konstruktor Injection, die MvvmCross Reflexion durchführen und automatisch Parameter bei der Objekterstellung lösen kann:
private readonly ISQLiteConnectionFactory _sqlFactory;
public DataAccessLayerService(ISQLiteConnectionFactory sqlFactory)
{
this._sqlFactory = sqlFactory;
}
Konstruktor Injection können Sie für Dienstleistungen sowie ViewModels. Dies ist wichtig zu verstehen, weil für Ihre Anwendung stellen in der Kern-Projekt entwickelt, in der Standardeinstellung sind, sind Cross-Plattform.
Sie können auch Dienstleistungen nutzen, die Cross-Plattform zu sein scheinen, aber für die Durchführung ist plattformspezifisch. Z. B. koordiniert eine Aufnahme mit der Kamera, immer des Benutzers, unter Verwendung einer Datenbank und so weiter. Mit Konstruktor Injection erhalten ViewModels eine Schnittstelle, wo die Umsetzung Plattform-spezifisch ist.
Um diesen Mechanismus der Injektion und plattformspezifischen Code weiter zu definieren, bietet MvvmCross ein Plugin-System. Das System können Sie erstellen und neue Funktionen zur Laufzeit zu injizieren. Jedes Plug-in ist ein Dienst, aufgeführt, eine Schnittstelle, die eine konkrete Implementierung für jede Plattform zur Verfügung gestellt hat. Das Plug-in-System registriert die Schnittstelle und Implementierung. Anwendungen belegen die Plug-ins mit DI. DI kann auch Plug-in Entwickler eine vereinfachte "mock" Implementierung Test-und Entwicklungszwecke bereitzustellen.
Aus Sicht eines Entwicklers ist ein Plug-in zu schreiben so einfach wie das Schreiben einer Schnittstelle. Erstellen Sie eine Klasse, die implementiert diese Schnittstelle und ein Plug-in-Ladeprogramm. Der Plugin-Loader ist eine Klasse, die die IMvxPluginLoader-Schnittstelle implementiert. Es registriert die Plug-in-Schnittstelle und Implementierung (mit Mvx.RegisterType) Wenn die EnsureLoaded-Methode aufgerufen.
Es gibt viele Plugins bereits verfügbar. Sie bieten Funktionen wie Dateizugriff, E-mail, JSON Konvertierung und so weiter. Hier finden Sie die meisten davon mit NuGet. Beachten Sie, dass einige Plug-ins nicht Implementierungen für alle Plattformen enthalten. Achten Sie auf dieses Detail, wenn Sie planen, ein Plug-in zu nutzen. Selbst wenn ein Plug-in Unterstützung für Ihre Plattform vorhanden ist, Sie können es einfacher finden, folgen dem Muster und implementieren die fehlende Plattform anstatt ein neues plug-in auf eigene Faust. Sollten Sie in diesem Fall einen Beitrag Ihrer Implementierung zurück an den Besitzer der Plug-in, so können andere auch es auch.
MvvmCross ist einen wertvollen Rahmen. Bedenken Sie bei der Entwicklung von mobiler Anwendungen — auch auf Android und iOS. Das MVVM-Muster, gepaart mit Datenbindung und Plug-ins, bietet ein leistungsstarkes System für die Erstellung hoch wart- und portable Code.
Thomas LeBrun ist Consultant bei Infinite Square, ein Französisch-Microsoft-Partner arbeiten auf Technologien wie Windows 8, Windows Phone, Windows Presentation Foundation (WPF), Silverlight, Oberfläche und mehr. Er schrieb zwei Bücher über WPF und MVVM-Muster. Er ist auch ein regelmäßiger Referent bei Gemeindeveranstaltungen. Sie können ihm folgen ist Blog unter blog.thomaslebrun.net und auf Twitter bei twitter.com/thomas_lebrun.
Unser Dank gilt dem folgenden technischen Experten von Microsoft für die Durchsicht dieses Artikels: Jared Bienz