可攜式類別庫 (PCL)
提示
可攜式類別庫 (PCL) 在最新版本的 Visual Studio 中被視為已淘汰。 雖然您仍然可以開啟、編輯和編譯 PCL,但對於新項目,建議您使用 .NET Standard 連結庫 來存取較大的 API 介面區。
建置跨平臺應用程式的關鍵元件是能夠跨各種平臺特定專案共享程序代碼。 不過,這很複雜,因為不同的平臺通常會使用不同的 .NET 基類庫 (BCL) 子集,因此實際上會建置至不同的 .NET Core 連結庫配置檔。 這表示每個平臺只能使用以相同配置檔為目標的類別庫,因此每個平臺似乎都需要個別的類別庫專案。
程式代碼共用有三個主要方法可解決此問題:.NET Standard 專案、共用資產專案和可攜式類別庫 (PCL) 專案。
- .NET Standard 專案 是共用 .NET 程式代碼的慣用方法,深入瞭解 .NET Standard 專案和 Xamarin。
- 共用資產專案 會使用單一檔案集,並提供一種快速且簡單的方式,在解決方案內共用程序代碼,並通常會採用條件式編譯指示詞來指定各種平臺的程式代碼路徑,以使用它(如需詳細資訊,請參閱 共用專案一文)。
- PCL 專案以支援一組已知 BCL 類別/功能的特定配置檔為目標。 不過,PCL 的缺點是,它們通常需要額外的架構工作,才能將配置檔特定的程式代碼分成自己的連結庫。
此頁面說明如何建立 以特定配置檔為目標的 PCL 專案,然後由多個平臺特定項目參考。
什麼是可攜式類別庫?
當您建立應用程式專案或連結庫專案時,產生的 DLL 僅限於在建立的特定平台上運作。 這可防止您為 Windows 應用程式撰寫元件,然後在 Xamarin.iOS 和 Xamarin.Android 上重新使用它。
不過,當您建立可攜式類別庫時,可以選擇您希望程式代碼執行的平台組合。 您在建立可攜式類別庫時所做的相容性選擇會轉譯成「配置檔」標識碼,其中描述連結庫支持的平臺。
下表顯示一些因 .NET 平台而異的功能。 若要撰寫保證在特定裝置/平臺上執行的 PCL 元件,您只需在建立專案時選擇所需的支援即可。
功能 | .NET Framework | UWP 應用程式 | Silverlight | Windows Phone | Xamarin |
---|---|---|---|---|---|
核心 | Y | Y | Y | Y | Y |
LINQ | Y | Y | Y | Y | Y |
IQueryable | Y | Y | Y | 7.5+ | Y |
序列化 | Y | Y | Y | Y | Y |
資料註解 | 4.0.3 + | Y | Y | Y |
Xamarin 數據行反映 Xamarin.iOS 和 Xamarin.Android 支援 Visual Studio 隨附的所有設定檔,而您所建立之任何連結庫中的功能可用性只會受到您選擇支援的其他平臺所限制。
這包括下列組合的設定檔:
- .NET 4 或 .NET 4.5
- silverlight 5
- Windows Phone 8
- UWP 應用程式
您可以深入瞭解 Microsoft 網站上的不同配置檔功能,並查看另一個社群成員的 PCL 配置檔摘要,其中包含支援的架構資訊和其他附注。
福利
- 集中式程式代碼共用 – 在可由其他連結庫或應用程式取用的單一專案中撰寫和測試程序代碼。
- 重構作業會影響解決方案中載入的所有程式代碼(可攜式類別庫和平臺特定專案)。
- PCL 專案可由方案中的其他專案輕鬆參考,也可以共用輸出元件,讓其他人在其解決方案中參考。
缺點
- 由於多個應用程式之間共用相同的可攜式類別庫,因此無法參考平臺特定連結庫(例如。Community.CsharpSqlite.WP7)。
- 可攜式類別庫子集可能不會包含可在 Android 的 MonoTouch 和 Mono 中取得的類別(例如 DllImport 或 System.IO.File)。
注意
可攜式類別庫已在最新版的 Visual Studio 中淘汰, 因此建議改用 .NET Standard 連結庫 。
在某種程度上,您可以使用提供者模式或相依性插入來規避這兩個缺點,針對可攜式類別庫中定義的介面或基類,在平台專案中撰寫實際實作的程序代碼。
此圖顯示使用可攜式類別庫來共用程式碼的跨平臺應用程式的架構,但也使用相依性插入傳入平臺相依功能:
Visual Studio for Mac 逐步解說
本節將逐步解說如何使用 Visual Studio for Mac 建立和使用可攜式類別庫。 如需完整的實作,請參閱 PCL 範例一節。
建立 PCL
將可攜式類別庫新增至您的解決方案,與新增一般連結庫專案非常類似。
在 [新增專案] 對話框中,選取 [多平台連結庫可攜式>連結庫>] 選項:
在 Visual Studio for Mac 中建立 PCL 時,會自動設定適用於 Xamarin.iOS 和 Xamarin.Android 的配置檔。 PCL 專案隨即出現,如下列螢幕快照所示:
PCL 現在已準備好新增程序代碼。 它也可以由其他項目參考(應用程式專案、連結庫專案,甚至是其他 PCL 專案)。
編輯 PCL 設定
若要檢視和變更此專案的 PCL 設定,請以滑鼠右鍵按兩下專案,然後選擇 [ 選項 > 建 > 置一般 ] 以查看此處顯示的畫面:
按兩下 [變更... ],變更此可攜式類別庫的目標配置檔。
如果在程式代碼已新增至 PCL 之後變更配置檔,如果程式代碼參考不屬於新選取配置檔的功能,連結庫就可能不再編譯。
使用 PCL
在 PCL 連結庫中撰寫程式代碼時,Visual Studio for Mac 編輯器會辨識所選配置檔的限制,並據以調整自動完成的選項。 例如,此螢幕快照顯示使用 Visual Studio for Mac 中使用的預設配置檔 (Profile136) 來 System.IO 自動完成選項 - 請注意,顯示大約一半可用類別的滾動條(事實上只有 14 個類別可用)。
與 Xamarin.iOS 或 Xamarin.Android 專案中的 System.IO 自動完成比較 – 有 40 個類別可供使用,包括常用的類別,例如 File
,且 Directory
不在任何 PCL 配置檔中。
這反映了使用 PCL 的基礎取捨 – 跨許多平台順暢地共用程式代碼的能力表示某些 API 無法供您使用,因為它們在所有可能的平臺之間沒有可比較的實作。
使用 PCL
建立 PCL 項目之後,您可以從任何相容的應用程式或連結庫專案新增參考,就像一般新增參考一樣。 在 Visual Studio for Mac 中,以滑鼠右鍵按兩下 [參考] 節點,然後選擇 [編輯參考...] ,然後切換至 [專案 ] 索引標籤,如下所示:
下列螢幕快照顯示TaskyPortable範例應用程式的Solutionpad,其中顯示底部的 PCL 連結庫,以及 Xamarin.iOS 專案中該 PCL 連結庫的參考。
PCL 的輸出(亦即產生的元件 DLL)也可以新增為大多數項目的參考。 這讓 PCL 成為運送跨平臺元件和連結庫的理想方式。
PCL 範例
TaskyPortable 範例應用程式示範可攜式類別庫如何搭配 Xamarin 使用。 以下是在 iOS 和 Android 上執行之結果應用程式的一些螢幕快照:
它共用一些純可攜式程式代碼的數據和邏輯類別,也會示範如何使用SQLite 資料庫實作的相依性插入來納入平臺特定需求。
解決方案結構如下所示(分別在 Visual Studio for Mac 和 Visual Studio 中):
由於 SQLite-NET 程式代碼具有平臺特定片段(在每一個不同作業系統上使用 SQLite 實作),因此已將其重構為可編譯為可攜式類別庫的抽象類,以及實作為 iOS 和 Android 專案中子類別的實際程式代碼。
TaskyPortableLibrary
可攜式類別庫在可支援之 .NET 功能中受到限制。 因為編譯成在多個平台上執行,所以無法使用 [DllImport]
SQLite-NET 中使用的功能。 相反地,SQLite-NET 會實作為抽象類,然後透過共用程式代碼的其餘部分來參考。 抽象 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();
}
共用程式代碼的其餘部分會使用抽象類從資料庫「儲存」和「擷取」物件。 在任何使用此抽象類別的應用程式中,我們必須傳入提供實際資料庫功能的完整實作。
TaskyAndroid 和 TaskyiOS
iOS 和 Android 應用程式專案包含使用者介面和其他平臺特定程式代碼,用來連接 PCL 中的共用程式代碼。
這些專案也包含可在該平台上運作的抽象資料庫 API 實作。 在 iOS 和 Android 上,Sqlite 資料庫引擎內建至作業系統,因此實作可以使用 [DllImport]
,提供資料庫連線的具體實作。 平臺特定實作程序代碼的摘錄如下所示:
[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);
您可以在範例程式代碼中看到完整的實作。
摘要
本文簡要討論了可攜式類別庫的優點和陷阱,示範如何從 Visual Studio for Mac 和 Visual Studio 內建立和使用 PCL;最後引進了完整的範例應用程式 – TaskyPortable – 顯示 PCL 運作情形。