Teilen über


Portable Klassenbibliotheken

Tipp

Portable Klassenbibliotheken (PORTABLE Class Libraries, PCLs) gelten als veraltet in den neuesten Versionen von Visual Studio. Während Sie PCLs weiterhin öffnen, bearbeiten und kompilieren können, wird es für neue Projekte empfohlen, .NET Standard-Bibliotheken für den Zugriff auf einen größeren API-Oberflächenbereich zu verwenden.

Eine wichtige Komponente des Erstellens plattformübergreifender Anwendungen ist in der Lage, Code über verschiedene plattformspezifische Projekte hinweg freizugeben. Dies ist jedoch kompliziert durch die Tatsache, dass unterschiedliche Plattformen häufig eine andere Untermenge der .NET Base Class Library (BCL) verwenden und daher tatsächlich auf ein anderes .NET Core Library Profile erstellt werden. Dies bedeutet, dass jede Plattform nur Klassenbibliotheken verwenden kann, die auf dasselbe Profil ausgerichtet sind, sodass sie scheinbar separate Klassenbibliotheksprojekte für jede Plattform benötigen.

Es gibt drei hauptansätze für die Codefreigabe, die dieses Problem beheben: .NET Standard-Projekte, Shared Asset Projects und Portable Class Library (PCL)-Projekte.

  • .NET Standard-Projekte sind der bevorzugte Ansatz für die Freigabe von .NET-Code, weitere Informationen zu .NET Standard-Projekten und Xamarin.
  • Freigegebene Objektprojekte verwenden eine einzelne Gruppe von Dateien und bieten eine schnelle und einfache Möglichkeit zum Freigeben von Code innerhalb einer Lösung und verwendet im Allgemeinen bedingte Kompilierungsdirektiven, um Codepfade für verschiedene Plattformen anzugeben, die sie verwenden werden (weitere Informationen finden Sie im Artikel "Freigegebene Projekte").
  • PCL-Projekte zielen auf bestimmte Profile ab, die einen bekannten Satz von BCL-Klassen/-Features unterstützen. Die untere Seite von PCL besteht jedoch darin, dass sie häufig zusätzliche Architekturaufwand erfordern, um profilspezifischen Code in ihre eigenen Bibliotheken zu trennen.

Auf dieser Seite wird erläutert, wie Sie ein PCL-Projekt erstellen, das auf ein bestimmtes Profil abzielt, auf das dann von mehreren plattformspezifischen Projekten verwiesen werden kann.

Was ist eine portable Klassenbibliothek?

Wenn Sie ein Anwendungsprojekt oder ein Bibliotheksprojekt erstellen, ist die resultierende DLL auf die Arbeit an der spezifischen Plattform beschränkt, für die sie erstellt wird. Dadurch wird verhindert, dass Sie eine Assembly für eine Windows-App schreiben und dann erneut auf Xamarin.iOS und Xamarin.Android verwenden.

Wenn Sie jedoch eine portable Klassenbibliothek erstellen, können Sie eine Kombination von Plattformen auswählen, auf denen Ihr Code ausgeführt werden soll. Die Kompatibilitätsoptionen, die Sie beim Erstellen einer portablen Klassenbibliothek treffen, werden in einen "Profil"-Bezeichner übersetzt, der beschreibt, welche Plattformen die Bibliothek unterstützt.

In der folgenden Tabelle sind einige der Features aufgeführt, die je nach .NET-Plattform variieren. Um eine PCL-Assembly zu schreiben, die garantiert auf bestimmten Geräten/Plattformen ausgeführt wird, wählen Sie einfach aus, welche Unterstützung erforderlich ist, wenn Sie das Projekt erstellen.

Funktion .NET Framework UWP-Apps Silverlight Windows Phone Xamarin
Core Y Y Y Y J
LINQ Y Y Y Y J
IQueryable Y Y J 7.5 und höher J
Serialisierung Y Y Y Y J
Datenanmerkungen 4.0.3 + Y Y J

Die Spalte "Xamarin" spiegelt die Tatsache wider, dass Xamarin.iOS und Xamarin.Android alle profile unterstützt, die mit Visual Studio ausgeliefert werden, und die Verfügbarkeit von Features in allen bibliotheken, die Sie erstellen, wird nur von den anderen Plattformen eingeschränkt, die Sie unterstützen möchten.

Dazu gehören Profile, die Kombinationen von:

  • .NET 4 oder .NET 4.5
  • Silverlight 5
  • Windows Phone 8
  • UWP-Apps

Weitere Informationen zu den Funktionen der verschiedenen Profile finden Sie auf der Website von Microsoft und sehen die PCL-Profilzusammenfassung eines anderen Communitymitglieds, die unterstützte Frameworkinformationen und andere Hinweise enthält.

Vorteile

  1. Zentrale Codefreigabe – Schreiben und Testen von Code in einem einzigen Projekt, das von anderen Bibliotheken oder Anwendungen genutzt werden kann.
  2. Umgestaltungsvorgänge wirken sich auf den gesamten code aus, der in der Lösung geladen wurde (die Portable Class Library und die plattformspezifischen Projekte).
  3. Das PCL-Projekt kann ganz einfach von anderen Projekten in einer Lösung referenziert werden, oder die Ausgabeassembly kann für andere freigegeben werden, um in ihren Lösungen darauf zu verweisen.

Nachteile

  1. Da die gleiche portable Klassenbibliothek zwischen mehreren Anwendungen gemeinsam genutzt wird, können plattformspezifische Bibliotheken nicht referenziert werden (z. B. Community.CsharpSqlite.WP7).
  2. Die Untermenge "Portable Class Library" enthält möglicherweise keine Klassen, die andernfalls in MonoTouch und Mono für Android verfügbar wären (z. B. DllImport oder System.IO.File).

Hinweis

Portable Klassenbibliotheken sind in der neuesten Version von Visual Studio veraltet, und .NET StandardBibliotheken werden stattdessen empfohlen.

In gewissem Maße können beide Nachteile mithilfe des Anbietermusters oder der Abhängigkeitsinjektion umgangen werden, um die tatsächliche Implementierung in den Plattformprojekten mit einer Schnittstelle oder Basisklasse zu codieren, die in der portablen Klassenbibliothek definiert ist.

Dieses Diagramm zeigt die Architektur einer plattformübergreifenden Anwendung, die eine portable Klassenbibliothek zum Freigeben von Code verwendet, aber auch die Verwendung von Abhängigkeitsinjektion zum Übergeben plattformabhängiger Features:

Dieses Diagramm zeigt die Architektur einer plattformübergreifenden Anwendung, die eine portable Klassenbibliothek zum Freigeben von Code verwendet, aber auch die Verwendung von Abhängigkeitsinjektion zum Übergeben plattformabhängiger Features

Visual Studio für Mac exemplarische Vorgehensweise

In diesem Abschnitt wird das Erstellen und Verwenden einer portablen Klassenbibliothek mithilfe von Visual Studio für Mac beschrieben. Eine vollständige Implementierung finden Sie im Abschnitt "PCL-Beispiel".

Erstellen einer PCL

Das Hinzufügen einer portablen Klassenbibliothek zu Ihrer Lösung ähnelt dem Hinzufügen eines regulären Bibliotheksprojekts.

  1. Wählen Sie im Dialogfeld "Neues Projekt" die Option "Portable Library Multiplatform > Library>" aus:

    Erstellen eines neuen PCL-Projekts

  2. Wenn eine PCL in Visual Studio für Mac erstellt wird, wird sie automatisch mit einem Profil konfiguriert, das für Xamarin.iOS und Xamarin.Android funktioniert. Das PCL-Projekt wird wie in diesem Screenshot dargestellt angezeigt:

    PCL-Projekt im Lösungspad

Die PCL kann jetzt code hinzugefügt werden. Sie kann auch von anderen Projekten (Anwendungsprojekte, Bibliotheksprojekte und sogar andere PCL-Projekte) referenziert werden.

Bearbeiten von PCL-Einstellungen

Um die PCL-Einstellungen für dieses Projekt anzuzeigen und zu ändern, klicken Sie mit der rechten Maustaste auf das Projekt, und wählen Sie "Optionen > : > Allgemein " aus, um den hier gezeigten Bildschirm anzuzeigen:

PCL-Projektoptionen zum Festlegen des Profils

Klicken Sie auf " Ändern..." , um das Zielprofil für diese portable Klassenbibliothek zu ändern.

Wenn das Profil geändert wird, nachdem code bereits zur PCL hinzugefügt wurde, kann die Bibliothek nicht mehr kompiliert werden, wenn der Code auf Features verweist, die nicht Teil des neu ausgewählten Profils sind.

Arbeiten mit einer PCL

Wenn Code in einer PCL-Bibliothek geschrieben wird, erkennt der Visual Studio für Mac-Editor die Einschränkungen des ausgewählten Profils und passt die Optionen für den automatischen Abschluss entsprechend an. Dieser Screenshot zeigt z. B. die Optionen für die automatische Fertigstellung für System.IO mithilfe des standardprofils (Profile136), das in Visual Studio für Mac verwendet wird. Beachten Sie, dass die Bildlaufleiste, die etwa die Hälfte der verfügbaren Klassen angibt, angezeigt werden (tatsächlich sind nur 14 Klassen verfügbar).

IntelliSense-Liste von 14 Klassen in der System.IO Klasse einer PCL

Vergleichen Sie dies mit dem System.IO autovervollständigen in einem Xamarin.iOS- oder Xamarin.Android-Projekt – es gibt 40 Klassen, einschließlich häufig verwendeter Klassen wie File und Directory die sich nicht in einem PCL-Profil befinden.

IntelliSense-Liste von 40 Klassen in .NET Framework System.IO Namespace

Dies spiegelt den zugrunde liegenden Kompromiss bei der Verwendung von PCL wider – die Möglichkeit, Code nahtlos auf vielen Plattformen freizugeben, bedeutet, dass bestimmte APIs nicht für Sie verfügbar sind, da sie über keine vergleichbaren Implementierungen auf allen möglichen Plattformen verfügen.

Verwenden von PCL

Nachdem ein PCL-Projekt erstellt wurde, können Sie einen Verweis auf das Projekt aus jedem kompatiblen Anwendungs- oder Bibliotheksprojekt auf die gleiche Weise hinzufügen, wie Sie normalerweise Verweise hinzufügen. Klicken Sie in Visual Studio für Mac mit der rechten Maustaste auf den Knoten "Verweise", und wählen Sie "Verweise bearbeiten" aus. Wechseln Sie dann wie gezeigt zur Registerkarte "Projekte":

Hinzufügen eines Verweises auf eine PCL über die Option

Der folgende Screenshot zeigt das Lösungspad für die TaskyPortable-Beispiel-App mit der PCL-Bibliothek unten und einen Verweis auf diese PCL-Bibliothek im Xamarin.iOS-Projekt.

TaskyPortable-Beispiellösung mit PCL-Projekt

Die Ausgabe einer PCL (d. h. die resultierende Assembly-DLL) kann auch als Verweis auf die meisten Projekte hinzugefügt werden. Dies macht PCL zu einer idealen Möglichkeit, plattformübergreifende Komponenten und Bibliotheken zu versenden.

PCL-Beispiel

Die TaskyPortable-Beispielanwendung veranschaulicht, wie eine portable Klassenbibliothek mit Xamarin verwendet werden kann. Hier sind einige Screenshots der resultierenden Apps, die unter iOS und Android ausgeführt werden:

Hier sind einige Screenshots der resultierenden Apps, die unter iOS, Android und Windows Telefon ausgeführt werden

Es gibt eine Reihe von Daten- und Logikklassen, die rein portierbaren Code sind, und es veranschaulicht außerdem, wie plattformspezifische Anforderungen mithilfe von Dependency Injection für die SQLite-Datenbankimplementierung integriert werden.

Die Lösungsstruktur ist unten dargestellt (in Visual Studio für Mac bzw. Visual Studio):

Die Lösungsstruktur wird hier in Visual Studio für Mac bzw. Visual Studio gezeigt.

Da der SQLite-NET-Code plattformspezifische Teile aufweist (um mit den SQLite-Implementierungen auf den verschiedenen Betriebssystemen zu arbeiten), wurde er zu Demonstrationszwecken in eine abstrakte Klasse umgestaltet, die in eine portable Klassenbibliothek kompiliert werden kann, und der tatsächliche Code, der als Unterklassen in den iOS- und Android-Projekten implementiert wird.

TaskyPortableLibrary

Die portable Klassenbibliothek ist in den .NET-Features eingeschränkt, die unterstützt werden können. Da sie für die Ausführung auf mehreren Plattformen kompiliert wird, kann sie keine Funktionalität verwenden [DllImport] , die in SQLite-NET verwendet wird. Stattdessen wird SQLite-NET als abstrakte Klasse implementiert und dann über den Rest des freigegebenen Codes referenziert. Unten sehen Sie einen Extrakt der abstrakten API:

public abstract class SQLiteConnection : IDisposable {

    public string DatabasePath { get; private set; }
    public bool TimeExecution { get; set; }
    public bool Trace { get; set; }
    public SQLiteConnection(string databasePath) {
         DatabasePath = databasePath;
    }
    public abstract int CreateTable<T>();
    public abstract SQLiteCommand CreateCommand(string cmdText, params object[] ps);
    public abstract int Execute(string query, params object[] args);
    public abstract List<T> Query<T>(string query, params object[] args) where T : new();
    public abstract TableQuery<T> Table<T>() where T : new();
    public abstract T Get<T>(object pk) where T : new();
    public bool IsInTransaction { get; protected set; }
    public abstract void BeginTransaction();
    public abstract void Rollback();
    public abstract void Commit();
    public abstract void RunInTransaction(Action action);
    public abstract int Insert(object obj);
    public abstract int Update(object obj);
    public abstract int Delete<T>(T obj);

    public void Dispose()
    {
        Close();
    }
    public abstract void Close();

}

Der re Standard der des freigegebenen Codes verwendet die abstrakte Klasse zum "Speichern" und "Abrufen" von Objekten aus der Datenbank. In jeder Anwendung, die diese abstrakte Klasse verwendet, müssen wir eine vollständige Implementierung übergeben, die die tatsächliche Datenbankfunktionalität bereitstellt.

TaskyAndroid und TaskyiOS

Die iOS- und Android-Anwendungsprojekte enthalten die Benutzeroberfläche und anderen plattformspezifischen Code, der zum Verkabeln des freigegebenen Codes in der PCL verwendet wird.

Diese Projekte enthalten auch eine Implementierung der abstrakten Datenbank-API, die auf dieser Plattform funktioniert. Unter iOS und Android ist das Sqlite-Datenbankmodul in das Betriebssystem integriert, sodass die Implementierung wie dargestellt verwendet werden kann [DllImport] , um die konkrete Implementierung der Datenbankkonnektivität bereitzustellen. Hier sehen Sie einen Auszug aus dem plattformspezifischen Implementierungscode:

[DllImport("sqlite3", EntryPoint = "sqlite3_open")]
public static extern Result Open(string filename, out IntPtr db);

[DllImport("sqlite3", EntryPoint = "sqlite3_close")]
public static extern Result Close(IntPtr db);

Die vollständige Implementierung kann im Beispielcode angezeigt werden.

Zusammenfassung

In diesem Artikel wurden kurz die Vorteile und Fallstricke von portablen Klassenbibliotheken erläutert, gezeigt, wie SIE PCLs aus Visual Studio für Mac und Visual Studio erstellen und nutzen können. Schließlich wurde eine vollständige Beispielanwendung – TaskyPortable – eingeführt, die eine PCL in Aktion zeigt.