Dajbych.net


Portable Libraries – jedna knihovna pro všechny platformy

, 6 minut čtení

net2010 logo

Portable Class Library je univerzální .NET knihovna. Je užitečná pro sdílení kódu například mezi WPF, Windows Phone a Metro style aplikacemi. Může obsahovat vše, co je pro platformy, pro které je určená, společné. Díky doplňku pro Visual Studio 2010 je možné ji začít používat ihned. Jelikož se platforma .NET poslední roky poněkud tříští, je Portable Library velmi vítaný tmelící prvek. Už není nutné kompilovat knihovny pro různé .NET platformy.

Úvod

Dříve byl jen .NET Framework. Po čase se však objevil Silverlight, poté Windows Phone, za ním Xbox 360 a nyní nastupuje Windows Runtime. To už je 5 různých platforem, na kterých běží .NET. Protože je však každá platforma svým způsobem značně specifická, jsou typy na každé z nich vždy trošku odlišné. Asi nemá smysl, aby Xbox 360 podporoval touch jako Metro style aplikace nebo obsahoval podporu pro Windows Forms. Windows Phone pro svůj SQL Server Compact nepotřebuje mohutný ADO.NET a Entity Framework, ale vystačí si tenčí vrstvou, která dokáže Code-First přístup a podporu LINQ zprostředkovat také. Silverlight musí mít úplně jiné třídy pro přístup k systému souborů. Portable Library dovoluje zvolit si platformy, pro které chceme vyvíjet. Máme poté k dispozici vše, co mají tyto platformy společné. Knihovna pak běží na všech zvolených platformách.

Často se vytváří jedna aplikace pro několik platforem. Portable Library typicky obsahuje kód, který by byl ve všech profilech stejný a je potřebný na každé z nich. Nejedná se o uživatelské rozhraní, protože každé zařízení ho má odlišné, ale především hlavní logiku aplikace. Portable Library je zejména pro Model a ViewModel a může také obsahovat referenci na službu.

Použití

Portable Library jde použít pro Silverlight, Xbox 360, Windows Phone 7, Windows Phone 8, Windows Runtime (Windows Metro style aplikace) a velký .NET Framework. Portable Class Library nejde cílit na .NET Micro Framework a SQL Server CLR. Projekt s Portable Library je pak možné otevřít jak ve Visual Studiu 2012, tak i ve 2010, je však potřeba doinstalovat doplněk Portable Library Tools 2 od Base Class Library týmu.

Po instalaci doplňku se objeví nový typ projektu.

Při jeho vytváření je nejprve nutné zvolit si profily, pro které chceme vyvíjet.

V lednu 2011 byla uvolněna první verze pro Visual Studio 2010. Umožňovala základní funkcionalitu, která měla být dostatečně přitažlivá pro vývojáře, aby jí zkusili a poslali zpětnou vazbu BCL týmu.

Druhá verze pro Visual Studio 2010 z května 2012 už se možnostmi neliší od té, která je ve Visual Studiu 2012.

Ve Visual Studio 2012 je podpora už zabudovaná.

Co je podporováno

Feature Area Silverlight 4 Silverlight 5 Windows Phone 7 Windows Phone 7.1 Metro Style Apps .NET Framework 4 .NET Framework 4.0.3 .NET Framework 4.5 XBOX 360
Core XML
LINQ
IQueryable
dynamic keyword support
Core WCF
Core Networking
View Models
Data Annotations
XLINQ
MEF
Data Contract Serialization
XML Serialization
JSon Serialization
System.Numerics
Task<T> support

Architektura s Portable Library

Základní princip spočívá ve vytvoření abstraktní třídy, která představuje Model. Má implementováno vše, co je pro všechny platformy společné. Tento model je umístěn v Portable Library. V ní je také ViewModel, který má v konstruktoru parametr, kterým se předává reference na konkrétní model z konkrétní platformy, který dědí z abstraktního modelu.

V praxi to však není tak jednoduché. Klíčová slova async a await typicky neznají všechny platformy, na které je potřebujeme cílit. Proto potřebujeme další rozhraní. Vytvořil jsem demo, které ilustruje základní princip. Děkuji Danielovi Plaistedovi za poskytnutí zdrojových kódů k task wrapperům.

Zdrojové kódy dema ke stažení.

Jak to funguje

Profily

Nejběžnější profil, se kterým se asi většina programátorů setkala, je .NET Framework Client Profile. Je to podmnožina .NET Frameworku pro aplikace na straně klienta. Neobsahuje ASP.NET, ale obsahuje Windows Forms a WPF. Silverlight je však platform profile, protože obsahuje na rozdíl od velkého .NET Frameworku rozdílnou implementaci. Obsahuje odlišný mscorelib.dll. Stejně je na tom také Windows Phone.

Profil je reprezentován množinou reference assemblies. Tyto assembly neobsahují instrukce IL (Intermediate Language), ale obsahují jen metadata. Překladač potřebuje metadata aby věděl, která volání může aplikace uskutečnit. Reference assemblies pro Metro style (Windows Runtime) profil naleznete v adresáři C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore. Spatříte v něm *mscorelib.*dll a System.Collections.dll. Proč je ale tato knihovna zvlášť, když jsou kolekce implementované v mscorelib.dll? Platforma .NET se skládá z několika vrstev, které jsou od sebe velmi pečlivě odděleny. Například mscorelib není závislý na ASP.NET. Postupem času, jak postupně přibývala prostředí, kde se .NET uplatňuje, se ukázalo, že by bylo dobré některé prvky rozdělit a umístit do různých vrstev. Profily se snaží tento nedostatek napravit. Proto jsou System.Collections.dll a System.Reflection.dll odděleny od System.Runtime.dll (což je nový název pro mscorelib.dll).

Fragmentace platforem

Různé .NET platformy mají mnoho společného, ale také se zásadně liší. Silverlight má odlišnou implementaci mscorelib. Xbox 360 je založen na .NET Compact Frameworku. Velký .NET obsahuje ASP.NET, který jinde, například na Windows Phone, nemá smysl.

Platformy se vzájemně liší zejména uživatelským rozhraním. Rozhraní INotifyPropertyChanged je jádro ViewModelu. V Silverlight je umístěno v knihovně System.Windows.dll, v .NETu však v knihovně Systém.dll. MEF (Managed Extensibility Framework) se vyskytuje jak ve velkém .NETu, tak i v Silverlightu. Nenaleznete ho však v Xboxu 360 a ve Windows Phone. Pokud je odškrtnete, můžete programovat moduly. Jakmile zaškrtnete Xbox 360, přicházíte o networking stack.

Využití původní funkcionality pro .NET Compact Framework

Strong type obsahuje jméno assembly, číslo její verze, hash veřejného klíče použitého k jejímu podpisu a retargetable bit. Ten se využíval pro schopnost běhu aplikace naprogramované proti .NET Compact Frameworku na desktopu, kde je velký .NET Framework. Tento bit je důležitý pro CLR, který obsahuje pevně zakódovanou tabulku říkající: „Pokud uvidíš assembly A s nastaveným retargetable bitem, tak místo ní použij assembly B.“

Pokud Portable Library obsahuje referenci na System.Net.dll, která obsahuje networkign stack, je retargetable flag nastaven. V Silverlightu tato knihovna existuje, ale ve velkém .NETu je její funkcionalita přímo v System.Core.dll. Proto je potřeba vytvořit stínovou assembly, která bude jen odkazovat na typy umístěné v jiné assembly.

Type forwarding

Type forwarding je to, díky čemuž fungují profily. Assembly nemusí obsahovat typ samotný i s jeho implementací, ale namísto toho může obsahovat jen typ s metadaty, které říkají, kde se ve skutečnosti daný typ nachází. Portable Library se tady programuje proti profilu. Naleznete ho v adresáři C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable. Tyto knihovny jsou sice technicky assembly, ale obsahují pouze metadata. Portable Library vlastně neobsahuje reference na konkrétní knihovny (i když technicky tomu tak stále je), ale referenci na knihovnu s metadaty. Tomuto typu reference se říká API Contract.

TypeRef, TypeSpec a TypeDef

Pokud nějaká assembly A používá nějaký typ z jiné assembly B, obsahuje ve skutečnosti jen TypeRef. TypeRef ukazuje na TypeSpec, který popisuje daný typ a nachází se v assembly s metadaty, oproti které je assembly A zkompilovaná. Assembly B, která se nachází na konkrétní platformě, obsahuje TypeDef, který je svázaný s TypeInfo. TypeSpec obsahuje dostatek informací k popsání typu, ale neobsahuje jich tolik jako TypeInfo. CLR se stará o provázání TypeSpec z profilu s TypeDef z platformy. Toto zavedení TypeSpec a TypeDef je největší viditelná změna v .NET Frameworku za poslední období. Dovoluje portable knihovnám běžet i na platformách, které vyjdou i v budoucnu, pokud budou podmnožinu, proti které je Portable Library naprogramována, obsahovat.

Článek byl sepsán pro Czech MSDN Blog.