Přenosné knihovny tříd (PCL)

Tip

Knihovny přenosných tříd (PCLS) se považují za zastaralé v nejnovějších verzích sady Visual Studio. I když stále můžete otevírat, upravovat a kompilovat seznamy PCLS, pro nové projekty se doporučuje pro přístup k větší ploše rozhraní API používat knihovny .NET Standard.

Klíčovou součástí vytváření multiplatformních aplikací je schopnost sdílet kód napříč různými projekty specifickými pro platformu. To je ale složité tím, že různé platformy často používají jinou podmnožinu knihovny základních tříd .NET (BCL), a proto jsou ve skutečnosti sestaveny do jiného profilu knihovny .NET Core. To znamená, že každá platforma může používat pouze knihovny tříd, které jsou cílem stejného profilu, aby se ukázalo, že pro každou platformu vyžadují samostatné projekty knihovny tříd.

Existují tři hlavní přístupy ke sdílení kódu, které řeší tento problém: projekty .NET Standard, projekty sdíleného assetu a projekty PCL (Portable Class Library).

  • Projekty .NET Standard jsou upřednostňovaným přístupem ke sdílení kódu .NET, přečtěte si další informace o projektech .NET Standard a Xamarinu.
  • Projekty sdílených prostředků používají jednu sadu souborů a nabízí rychlý a jednoduchý způsob sdílení kódu v rámci řešení a obecně používá direktivy podmíněné kompilace k určení cest kódu pro různé platformy, které ho budou používat (další informace najdete v článku Sdílené projekty).
  • Projekty PCL cílí na specifické profily, které podporují známou sadu tříd/funkcí seznamu BCL. Nevýhodou pcL je ale to, že často vyžadují dodatečné architektonické úsilí k oddělení specifického kódu profilu do vlastních knihoven.

Tato stránka vysvětluje, jak vytvořit projekt PCL , který cílí na konkrétní profil, na který pak může odkazovat více projektů specifických pro platformu.

Co je přenosná knihovna tříd?

Při vytváření projektu aplikace nebo projektu knihovny je výsledná knihovna DLL omezena na práci na konkrétní platformě, pro kterou je vytvořena. To vám zabrání v zápisu sestavení pro aplikaci pro Windows a následné opětovné použití v Xamarin.iOS a Xamarin.Android.

Při vytváření knihovny přenosných tříd ale můžete zvolit kombinaci platforem, na kterých má váš kód běžet. Volby kompatibility, které provedete při vytváření přenosné knihovny tříd, se přeloží do identifikátoru profilu, který popisuje, které platformy knihovna podporuje.

V následující tabulce jsou uvedeny některé funkce, které se liší podle platformy .NET. Pokud chcete napsat sestavení PCL, které je zaručeno spuštění na konkrétních zařízeních nebo platformách, jednoduše zvolíte, která podpora se vyžaduje při vytváření projektu.

Funkce .NET Framework Aplikace pro UPW Silverlight Windows Phone Xamarin
Základ Y Y Y Y Y
LINQ Y Y Y Y Y
IQueryable Y Y Y 7.5 nebo novější Y
Serializace Y Y Y Y Y
Datové poznámky 4.0.3 + Y Y Y

Sloupec Xamarin odráží skutečnost, že Xamarin.iOS a Xamarin.Android podporují všechny profily dodávané se sadou Visual Studio a dostupnost funkcí ve všech vytvořených knihovnách bude omezena pouze ostatními platformami, které se rozhodnete podporovat.

Patří sem profily, které jsou kombinací:

  • .NET 4 nebo .NET 4.5
  • Silverlight 5
  • Windows Phone 8
  • Aplikace pro UPW

Další informace o možnostech různých profilů najdete na webu Microsoftu a podívat se na souhrn profilu PCL jiného člena komunity, který obsahuje informace o podporovaném rozhraní a další poznámky.

Benefity

  1. Centralizované sdílení kódu – psaní a testování kódu v jednom projektu, který může využívat jiné knihovny nebo aplikace.
  2. Operace refaktoringu ovlivní veškerý kód načtený v řešení (přenosná knihovna tříd a projekty specifické pro platformu).
  3. Projekt PCL lze snadno odkazovat na jiné projekty v řešení nebo je možné sdílet výstupní sestavení, aby ostatní mohli odkazovat na jejich řešení.

Nevýhody

  1. Vzhledem k tomu, že stejná přenosná knihovna tříd je sdílena mezi více aplikacemi, nelze na knihovny specifické pro platformu odkazovat (např. Community.CsharpSqlite.WP7).
  2. Podmnožina knihovny přenosných tříd nemusí obsahovat třídy, které by jinak byly k dispozici v MonoTouch i Mono pro Android (například DllImport nebo System.IO.File).

Poznámka:

Knihovny přenosných tříd jsou zastaralé v nejnovější verzi sady Visual Studio a doporučuje se místo toho knihovny .NET Standard.

Do určité míry lze obě nevýhody obejít pomocí vzoru zprostředkovatele nebo injektáže závislostí k kódování skutečné implementace v projektech platformy proti rozhraní nebo základní třídě definované v knihovně přenosných tříd.

Tento diagram znázorňuje architekturu multiplatformní aplikace využívající knihovnu přenosných tříd ke sdílení kódu, ale také použití injektáže závislostí pro předávání funkcí závislých na platformě:

This diagram shows the architecture of a cross-platform application using a Portable Class Library to share code, but also using Dependency Injection to pass in platform-dependent features

Visual Studio pro Mac návod

Tato část vás provede vytvořením a použitím přenosné knihovny tříd pomocí Visual Studio pro Mac. Kompletní implementaci najdete v části s příklady PCL.

Vytvoření PCL

Přidání přenosné knihovny tříd do vašeho řešení je velmi podobné přidání běžného projektu knihovny.

  1. V dialogovém okně Nový projekt vyberte možnost Přenosná knihovna multiplatformní > knihovny>:

    Create a new PCL project

  2. Když se pcL vytvoří v Visual Studio pro Mac automaticky se nakonfiguruje s profilem, který funguje pro Xamarin.iOS a Xamarin.Android. Projekt PCL se zobrazí, jak je znázorněno na tomto snímku obrazovky:

    PCL project in the solution pad

PCL je teď připravený na přidání kódu. Lze na něj také odkazovat jinými projekty (projekty aplikací, projekty knihovny a dokonce i jiné projekty PCL).

Úprava nastavení PCL

Pokud chcete zobrazit a změnit nastavení PCL pro tento projekt, klikněte pravým tlačítkem myši na projekt a zvolte Možnosti > Sestavení > obecné , aby se zobrazila obrazovka zobrazená tady:

PCL Project Options to set the profile

Chcete-li změnit cílový profil pro tuto přenosnou knihovnu tříd, klikněte na tlačítko Změnit... .

Pokud se profil změní po přidání kódu do pcL, je možné, že knihovna už nebude kompilovat, pokud kód odkazuje na funkce, které nejsou součástí nově vybraného profilu.

Práce s PCL

Když je kód napsán v knihovně PCL, editor Visual Studio pro Mac rozpozná omezení vybraného profilu a odpovídajícím způsobem upraví možnosti automatického dokončování. Tento snímek obrazovky například ukazuje možnosti automatického dokončování pro System.IO pomocí výchozího profilu (Profile136) používaného v Visual Studio pro Mac – všimněte si posuvníku, který označuje přibližně polovinu dostupných tříd (ve skutečnosti je k dispozici pouze 14 tříd).

Intellisense list of 14 classes in the System.IO class of a PCL

Porovnejte to s System.IO automatickým dokončováním v projektu Xamarin.iOS nebo Xamarin.Android – k dispozici je 40 tříd, včetně běžně používaných tříd, jako File jsou a Directory které nejsou v žádném profilu PCL.

Intellisense list of 40 classes in .NET Framework System.IO namespace

To odráží základní kompromis při používání PCL – možnost bezproblémově sdílet kód napříč mnoha platformami znamená, že určitá rozhraní API nejsou pro vás dostupná, protože nemají srovnatelné implementace napříč všemi možnými platformami.

Použití PCL

Po vytvoření projektu PCL k němu můžete přidat odkaz z libovolného kompatibilního projektu aplikace nebo knihovny stejným způsobem, jakým obvykle přidáváte odkazy. V Visual Studio pro Mac klikněte pravým tlačítkem myši na uzel Reference a zvolte Upravit odkazy... pak přepněte na kartu Projekty, jak je znázorněno:

Add a reference to a PCL via Edit References option

Následující snímek obrazovky ukazuje panel řešení ukázkové aplikace TaskyPortable zobrazující knihovnu PCL v dolní části a odkaz na danou knihovnu PCL v projektu Xamarin.iOS.

TaskyPortable sample solution showing PCL project

Výstup z knihovny PCL (tj. výsledné knihovny DLL sestavení) lze také přidat jako odkaz na většinu projektů. Díky tomu je PCL ideální způsob, jak dodávat multiplatformní komponenty a knihovny.

Příklad PCL

Ukázková aplikace TaskyPortable ukazuje, jak lze s Xamarinem použít přenosnou knihovnu tříd. Tady je několik snímků obrazovky s výslednými aplikacemi běžícími na iOSu a Androidu:

Here are some screenshots of the resulting apps running on iOS, Android and Windows Phone

Sdílí řadu datových a logických tříd, které jsou čistě přenosný kód, a také ukazuje, jak začlenit požadavky specifické pro platformu pomocí injektáže závislostí pro implementaci databáze SQLite.

Struktura řešení je zobrazená níže (v Visual Studio pro Mac a sadě Visual Studio):

The solution structure is shown here in Visual Studio for Mac and Visual Studio respectively

Vzhledem k tomu, že kód SQLite-NET obsahuje části specifické pro platformu (pro práci s implementacemi SQLite v každém jiném operačním systému) pro demonstrační účely, které byly refaktorovány do abstraktní třídy, které lze zkompilovat do knihovny přenosných tříd, a skutečný kód implementovaný jako podtřídy v projektech iOS a Android.

TaskyPortableLibrary

Přenosná knihovna tříd je omezená v funkcích .NET, které může podporovat. Protože je zkompilován tak, aby běžel na více platformách, nemůže využívat [DllImport] funkce, které se používají v SQLite-NET. Místo toho se SQLite-NET implementuje jako abstraktní třída a pak se odkazuje přes zbytek sdíleného kódu. Extrakce abstraktního rozhraní API je znázorněná níže:

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

}

Zbývající část sdíleného kódu používá abstraktní třídu k "ukládání" a "načtení" objektů z databáze. V každé aplikaci, která používá tuto abstraktní třídu, musíme předat úplnou implementaci, která poskytuje skutečné databázové funkce.

TaskyAndroid a TaskyiOS

Projekty aplikací pro iOS a Android obsahují uživatelský rozhraní a jiný kód specifický pro platformu, který se používá k připojení sdíleného kódu v PCL.

Tyto projekty také obsahují implementaci abstraktního databázového rozhraní API, které funguje na této platformě. V iOSu a Androidu je databázový stroj Sqlite integrovaný do operačního systému, takže implementace může použít [DllImport] , jak je znázorněno, k zajištění konkrétní implementace připojení k databázi. Tady je ukázka kódu implementace specifického pro platformu:

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

Úplnou implementaci si můžete prohlédnout v ukázkovém kódu.

Shrnutí

Tento článek stručně probral výhody a nástrahy přenosných knihoven tříd, ukázal, jak vytvářet a využívat knihovny PCLS z Visual Studio pro Mac a sady Visual Studio; a nakonec představil kompletní ukázkovou aplikaci – TaskyPortable – která ukazuje PCL v akci.