Bibliothèques de classes portables (PCL)

Conseil

Les bibliothèques de classes portables (PCL) sont considérées comme déconseillées dans les dernières versions de Visual Studio. Bien que vous puissiez toujours ouvrir, modifier et compiler des LISTES de contrôle d’accès, pour les nouveaux projets, il est recommandé d’utiliser des bibliothèques .NET Standard pour accéder à une plus grande surface d’API.

Un composant clé de la création d’applications multiplateformes est en mesure de partager du code entre différents projets spécifiques à la plateforme. Toutefois, cela est compliqué par le fait que différentes plateformes utilisent souvent un sous-ensemble différent de la bibliothèque de classes de base .NET (BCL), et sont donc réellement générées à un autre profil de bibliothèque .NET Core. Cela signifie que chaque plateforme ne peut utiliser que des bibliothèques de classes ciblées sur le même profil afin qu’elles semblent nécessiter des projets de bibliothèque de classes distincts pour chaque plateforme.

Il existe trois approches majeures pour le partage de code qui résolvent ce problème : les projets .NET Standard, les projets de ressources partagées et les projets de bibliothèque de classes portables (PCL).

  • Les projets .NET Standard sont l’approche recommandée pour le partage de code .NET, en savoir plus sur les projets .NET Standard et Xamarin.
  • Les projets de ressources partagées utilisent un ensemble unique de fichiers et offrent un moyen rapide et simple de partager du code au sein d’une solution et utilise généralement des directives de compilation conditionnelle pour spécifier des chemins de code pour différentes plateformes qui l’utiliseront (pour plus d’informations, consultez l’article Projets partagés).
  • Les projets PCL ciblent des profils spécifiques qui prennent en charge un ensemble connu de classes/fonctionnalités BCL. Toutefois, le côté inférieur à la bibliothèque PCL est qu’ils nécessitent souvent un effort architectural supplémentaire pour séparer le code spécifique du profil dans leurs propres bibliothèques.

Cette page explique comment créer un projet PCL qui cible un profil spécifique, qui peut ensuite être référencé par plusieurs projets spécifiques à la plateforme.

Qu’est-ce qu’une bibliothèque de classes portable ?

Lorsque vous créez un projet d’application ou un projet de bibliothèque, la DLL résultante est limitée à l’utilisation de la plateforme spécifique pour laquelle elle est créée. Cela vous empêche d’écrire un assembly pour une application Windows, puis de le réutiliser sur Xamarin.iOS et Xamarin.Android.

Toutefois, lorsque vous créez une bibliothèque de classes portable, vous pouvez choisir une combinaison de plateformes sur lesquelles vous souhaitez que votre code s’exécute. Les choix de compatibilité que vous effectuez lors de la création d’une bibliothèque de classes portables sont traduits en identificateur « Profil », qui décrit les plateformes prises en charge par la bibliothèque.

Le tableau ci-dessous présente certaines des fonctionnalités qui varient selon la plateforme .NET. Pour écrire un assembly PCL garanti pour s’exécuter sur des appareils/plateformes spécifiques, vous choisissez simplement la prise en charge requise lorsque vous créez le projet.

Fonctionnalité .NET Framework Applications UWP Silverlight Windows Phone Xamarin
Core A O O O A
LINQ A O O O A
IQueryable A O A 7.5+ O
Sérialisation A O O O A
Annotations de données 4.0.3 + A O A

La colonne Xamarin reflète le fait que Xamarin.iOS et Xamarin.Android prennent en charge tous les profils fournis avec Visual Studio, et la disponibilité des fonctionnalités dans toutes les bibliothèques que vous créez ne sera limitée que par les autres plateformes que vous choisissez de prendre en charge.

Cela inclut les profils qui sont des combinaisons de :

  • .NET 4 ou .NET 4.5
  • Silverlight 5
  • Windows Phone 8
  • Applications UWP

Vous pouvez en savoir plus sur les fonctionnalités des différents profils sur le site web de Microsoft et voir le résumé du profil PCL d’un autre membre de la communauté, qui inclut les informations de framework prises en charge et d’autres notes.

Avantages

  1. Partage de code centralisé : écrivez et testez du code dans un projet unique qui peut être consommé par d’autres bibliothèques ou applications.
  2. Les opérations de refactorisation affectent tout le code chargé dans la solution (bibliothèque de classes portables et projets spécifiques à la plateforme).
  3. Le projet PCL peut être facilement référencé par d’autres projets dans une solution, ou l’assembly de sortie peut être partagé pour que d’autres personnes puissent référencer leurs solutions.

Inconvénients

  1. Étant donné que la même bibliothèque de classes portables est partagée entre plusieurs applications, les bibliothèques spécifiques à la plateforme ne peuvent pas être référencées (par exemple. Community.CsharpSqlite.WP7).
  2. Le sous-ensemble bibliothèque de classes portable peut ne pas inclure de classes qui seraient autrement disponibles dans MonoTouch et Mono pour Android (par exemple, DllImport ou System.IO.File).

Remarque

Les bibliothèques de classes portables ont été déconseillées dans la dernière version de Visual Studio et les bibliothèques .NET Standard sont recommandées à la place.

Dans une certaine mesure, les deux inconvénients peuvent être contournés à l’aide du modèle fournisseur ou de l’injection de dépendances pour coder l’implémentation réelle dans les projets de plateforme sur une interface ou une classe de base définie dans la bibliothèque de classes portable.

Ce diagramme montre l’architecture d’une application multiplateforme à l’aide d’une bibliothèque de classes portable pour partager du code, mais également en utilisant l’injection de dépendances pour transmettre des fonctionnalités dépendantes de la plateforme :

Ce diagramme montre l’architecture d’une application multiplateforme à l’aide d’une bibliothèque de classes portable pour partager du code, mais également en utilisant l’injection de dépendances pour transmettre des fonctionnalités dépendantes de la plateforme

procédure pas à pas Visual Studio pour Mac

Cette section explique comment créer et utiliser une bibliothèque de classes portable à l’aide de Visual Studio pour Mac. Reportez-vous à la section Exemple pcL pour une implémentation complète.

Création d’une bibliothèque PCL

L’ajout d’une bibliothèque de classes portable à votre solution est très similaire à l’ajout d’un projet de bibliothèque standard.

  1. Dans la boîte de dialogue Nouveau projet, sélectionnez l’option Bibliothèque > portable multiplateforme > :

    Créer un projet PCL

  2. Lorsqu’un PCL est créé dans Visual Studio pour Mac il est automatiquement configuré avec un profil qui fonctionne pour Xamarin.iOS et Xamarin.Android. Le projet PCL s’affiche comme indiqué dans cette capture d’écran :

    Projet PCL dans le panneau solution

La bibliothèque PCL est maintenant prête à être ajoutée au code. Il peut également être référencé par d’autres projets (projets d’application, projets de bibliothèque et même d’autres projets PCL).

Modification des paramètres PCL

Pour afficher et modifier les paramètres PCL de ce projet, cliquez avec le bouton droit sur le projet et choisissez Options > Build > General pour afficher l’écran illustré ici :

Options de projet PCL pour définir le profil

Cliquez sur Modifier... pour modifier le profil cible de cette bibliothèque de classes portable.

Si le profil est modifié une fois que le code a déjà été ajouté au PCL, il est possible que la bibliothèque ne se compile plus si le code référence les fonctionnalités qui ne font pas partie du profil nouvellement sélectionné.

Utilisation d’une bibliothèque PCL

Lorsque le code est écrit dans une bibliothèque PCL, l’éditeur Visual Studio pour Mac reconnaît les limitations du profil sélectionné et ajuste les options de saisie semi-automatique en conséquence. Par exemple, cette capture d’écran montre les options de saisie semi-automatique pour System.IO à l’aide du profil par défaut (Profile136) utilisé dans Visual Studio pour Mac. Notez que la barre de défilement indique qu’environ la moitié des classes disponibles sont affichées (en fait, il n’y a que 14 classes disponibles).

Liste IntelliSense de 14 classes dans la classe System.IO d’une bibliothèque PCL

Comparez cela avec le System.IO la saisie semi-automatique dans un projet Xamarin.iOS ou Xamarin.Android : il existe 40 classes disponibles, notamment des classes couramment utilisées comme File et Directory qui ne se trouvent pas dans un profil PCL.

Liste IntelliSense de 40 classes dans l’espace de noms .NET Framework System.IO

Cela reflète le compromis sous-jacent de l’utilisation de pcL : la possibilité de partager du code en toute transparence sur de nombreuses plateformes signifie que certaines API ne sont pas disponibles, car elles n’ont pas d’implémentations comparables sur toutes les plateformes possibles.

Utilisation de PCL

Une fois qu’un projet PCL a été créé, vous pouvez y ajouter une référence à partir de n’importe quel projet d’application ou de bibliothèque compatible de la même façon que vous ajoutez normalement des références. Dans Visual Studio pour Mac, cliquez avec le bouton droit sur le nœud Références et choisissez Modifier les références, puis basculez vers l’onglet Projets, comme indiqué :

Ajouter une référence à un PCL via l’option Modifier les références

La capture d’écran suivante montre le panneau Solution de l’exemple d’application TaskyPortable, montrant la bibliothèque PCL en bas et une référence à cette bibliothèque PCL dans le projet Xamarin.iOS.

Exemple de solution TaskyPortable montrant le projet PCL

La sortie d’une bibliothèque PCL (par exemple, la DLL d’assembly résultante) peut également être ajoutée comme référence à la plupart des projets. Cela rend PCL un moyen idéal d’expédier des composants et des bibliothèques multiplateformes.

Exemple PCL

L’exemple d’application TaskyPortable montre comment une bibliothèque de classes portable peut être utilisée avec Xamarin. Voici quelques captures d’écran des applications résultantes s’exécutant sur iOS et Android :

Voici quelques captures d’écran des applications résultantes s’exécutant sur iOS, Android et Windows Téléphone

Il partage un certain nombre de classes de données et de logiques qui sont du code purement portable, et montre également comment incorporer des exigences spécifiques à la plateforme à l’aide de l’injection de dépendances pour l’implémentation de la base de données SQLite.

La structure de la solution est illustrée ci-dessous (dans Visual Studio pour Mac et Visual Studio respectivement) :

La structure de solution est présentée ici dans Visual Studio pour Mac et Visual Studio respectivement

Étant donné que le code SQLite-NET comporte des éléments spécifiques à la plateforme (pour utiliser les implémentations SQLite sur chaque système d’exploitation différent) à des fins de démonstration, il a été refactorisé dans une classe abstraite qui peut être compilée dans une bibliothèque de classes portable et le code réel implémenté en tant que sous-classes dans les projets iOS et Android.

TaskyPortableLibrary

La bibliothèque de classes portables est limitée dans les fonctionnalités .NET qu’elle peut prendre en charge. Étant donné qu’il est compilé pour s’exécuter sur plusieurs plateformes, il ne peut pas utiliser de [DllImport] fonctionnalités utilisées dans SQLite-NET. Au lieu de cela, SQLite-NET est implémenté en tant que classe abstraite, puis référencée via le reste du code partagé. Un extrait de l’API abstraite est illustré ci-dessous :

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();

}

Le reste du code partagé utilise la classe abstraite pour « stocker » et « récupérer » des objets de la base de données. Dans toute application qui utilise cette classe abstraite, nous devons passer une implémentation complète qui fournit les fonctionnalités de base de données réelles.

TaskyAndroid et TaskyiOS

Les projets d’application iOS et Android contiennent l’interface utilisateur et d’autres codes spécifiques à la plateforme utilisés pour connecter le code partagé dans la bibliothèque PCL.

Ces projets contiennent également une implémentation de l’API de base de données abstraite qui fonctionne sur cette plateforme. Sur iOS et Android, le moteur de base de données Sqlite est intégré au système d’exploitation. L’implémentation peut donc être utilisée [DllImport] comme indiqué pour fournir l’implémentation concrète de la connectivité de base de données. Voici un extrait du code d’implémentation spécifique à la plateforme :

[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);

L’implémentation complète est visible dans l’exemple de code.

Résumé

Cet article a brièvement abordé les avantages et les pièges des bibliothèques de classes portables, a montré comment créer et consommer des PCL à partir de Visual Studio pour Mac et de Visual Studio ; et enfin introduit un exemple complet d’application – TaskyPortable – qui montre une bibliothèque PCL en action.