.NET MAUI 簡介:從 .NET 歷史說起

上一篇文章(以及示範影片)快速體驗了一下 .NET MAUI app 執行於 Android 模擬器的過程,這次要從 .NET 歷史來介紹 MAUI。



印象中,「寫一次,執行於多種平台」最早是由一手打造 Java 的昇陽公司(Sun Microsystems)提出來的。在那之前,程式設計師都是直接面對底層作業系統的 API 來寫程式。後來,Java 在程式設計師與作業系統之間提供了一層轉換機制,讓 Java 應用程式在執行時通過這個轉換層來對應至底層作業系統的 API。這個執行時期的轉換層叫做 JVM(Java Virtual Machine)。如此一來,只要各家作業系統上面都有運行 JVM,開發人員就可以忽略底層作業系統的差異,只需要專注在與 JVM 搭配的 API 程式庫,從而實現了「寫一次,執行於各家作業平台」的目標。

關於跨平台程式設計,微軟也有提出自己的答案,那便是 2000 年推出的 .NET Framework。


與 Java 類似,.NET Framework 也有一個執行時期的轉換層,叫做 CLR(Common Language Runtime),以及與之搭配的一套 API 程式庫,叫做 BCL(Base Class Library)。.NET 開發人員通常只針對 BCL 來寫程式,而只在某些特定場合才需要直接存取 Windows 作業系統層次的 API。與 Java 不同的是,.NET Framework 只是讓開發人員能夠更輕鬆地設計出「跨不同 Windows 版本」的應用程式,而不能跨到 Windows 之外的作業系統。換言之,.NET Framework 是「Windows 限定」。此限制一直到 .NET Core 出現才開始獲得一些解放。


儘管 .NET Core 應用程式可在 Windows、Mac、和 Linux 作業系統上運行,但是侷限在命令列和伺服器端的應用(例如網站和 Web APIs),因為 GUI(圖形使用者介面)的部分並未實現跨平台。其實在更早之前,已經有一群人為了讓 .NET 應用程式能夠跨平台而努力,其結晶便是開源專案 Mono。


早期版本的 Mono 可以說是開源版本的 .NET Framework,它有自己的 C# 編譯器、Mono 版本的 ASP.NET 和 Windows Forms。經過一些版本演進,Mono 不僅支援 Windows、Mac、Linux,還納入了 iOS、Android 等行動作業系統。後來,參與 Mono 專案的一些開發人員組成了一家公司:Xamarin,而這個團隊打造了一套跨平台 UI 的框架,叫做 Xamarin Forms。以往,由於 iOS 和 Android 平台的差異,開發人員必須學習兩套原生 APIs 和特定平台的程式語言,而 Xamarin 讓 .NET 開發人員能夠使用自己熟悉的 C# 語言來開發跨 iOS 與 Android 行動裝置的應用程式,在開發成本與效率方面頗具優勢。


Xamarin 公司是在 2014 年推出 Xamarin Forms,然後在 2016 年併入微軟旗下。


於是乎,.NET 生態系開始複雜起來,我們有 .NET Framework、.NET Core、Mono、和 Xamarin。它們彼此有相似與重疊之處,也各有不同程度的差異。為了簡化、避免混淆,微軟開始在框架演進過程中對名稱做了調整,從 .NET 5 開始捨棄「Core」,單純叫「.NET」,而早期的「.NET Framework」就繼續讓它維持「Windows 限定」的角色。


基本上,.NET 5 可以說是 .NET Framework 與 .NET Core 的合體,不僅可以開發「跨平台的」ASP.NET 應用程式,也可以開發 Windows Forms 和 WPF 應用程式。然而,.NET 5 的 GUI 框架依然只能運行在 Windows 上面,就像拼圖缺了一塊……直到 .NET 6 出現。


在 .NET 6,連 GUI 的部分都能夠跨平台了。擔此重任的,是一個叫做 MAUI 的 UI 框架。儘管 MAUI 骨子裡有 Xamarin Forms 的基因,然而作為後繼者,它有著新的立足點和更遠大的目標,為實現「寫一次,執行於多種平台」願景持續添加柴火。


什麼是 .NET MAUI?

MAUI 的全名是 .NET Multi-platform App UI,它是微軟的開源專案,一個新的跨平台 UI 框架,可執行於 Windows、macOS、iOS、和 Android。筆者寫下這段文字時,MAUI 尚未支援 Linux UI 應用程式,而根據微軟文件,Linux UI 的部分將會由社群協助打造,而不會由微軟官方支援。

註:.NET 已經支援 Linux 命令列與服務類型的應用程式。


也就是說,當我們用 C# 開發一個 MAUI 應用程式,它將能夠執行於所有 MAUI 支援的作業平台。UI 的部分,可以使用 XAML(一種標記語言),也可以用 C# 或 F# 程式碼來建構使用者介面。


底下是 .NET MAUI 應用程式的架構圖:


依序由上而下來看,最上面那層是我們的應用程式,下面緊接著 .NET MAUI API。圖中那個較短的箭頭表示我們只要對 .NET MAUI 這層 API 來寫程式,便可支援底層的四種作業平台。這是因為 .NET MAUI 在背後替我們處理了 API 對應的繁複工作。圖的第三層可以看到,MAUI 往下對應的分別是 .NET 提供的四種特定平台的函式庫:.NET for Android、.NET for iOS、.NET for macOS、和 WinUI。圖中那個比較長的箭頭所代表的意思是,若有需要,開發人員也可以直接使用這四種特定平台的 .NET 函式庫來分別設計各平台的 UI——不過,這種作法即表示我們必須個別維護特定平台的程式碼。


在四種特定平台的 .NET 函式庫之下,則是跨平台的 .NET BCL(Base Class Library)。BCL 提供了許多常用的基礎類別,像是串列、泛型等等。在 BCL 之下,則是負責應用程式執行時期相關工作的 .NET runtime。這層 runtime 有兩種版本,一個是 Mono,負責處理 Android、iOS、和 macOS 平台,另一個則是 WinRT,負責 Windows 平台。


以上所述,是從比較高的位置來俯瞰 .NET MAUI 應用程式的架構。再往細一點說,.NET MAUI app 可以在 Windows 或 Mac 電腦上面進行開發,而在編譯時,我們撰寫的 C# 程式碼將會被編譯成各原生平台的檔案格式:

  • Android:C# 程式碼會被編譯成中介語言(IL),然後在 app 啟動時立即(just-in-time;JIT)編譯成 Android 平台的原生組件。
  • iOS:C# 程式碼會直接編譯成原生的 ARM 代碼。相較於剛才說的 JIT 模式,這種直接編譯成原生代碼的作法叫做 AOT(ahead-of-time)編譯。
  • macOS:透過蘋果公司提供的 Mac Catalyst 來將我們的 iOS app 轉換成可執行於 macOS 平台的版本。
  • Windows:使用 WinUI 函式庫(寫作當下的版本是 WinUI 3)來建立 Windows 平台上的原生 app。

備註:若有需要,也可以對 Android app 使用 AOT 編譯。

請注意,如果要編譯 iOS 和 macOS 版本的 MAUI 應用程式,我們手邊還得有一台 Mac 電腦才行。目前我尚未實際做過這個部分(Mac 電腦還沒買啊!),不過從微軟的技術文件可以大概知道,Visual Studio 2022 是透過它的 Pair to Mac 功能來連線到 Mac 電腦,並執行該電腦上的 Mac 建置工具來編譯 iOS app。


結語

.NET MAUI 的出現,對於維護十幾年 Windows Forms 應用程式的老園丁,同時也是行動 app 苦手的我來說,簡直就像隧道盡頭冒出一道光(就是這個光!)。加上 Blazor Hybrid 技術,讓 GUI 應用程式也能嵌入 Web UI,為 .NET 開發人員提供了更多選項,可針對不同需求來選擇合適的解決方案。


或許更重要的是,作為 Xamarin Forms 的繼承者,MAUI 已經成為 .NET 家族的成員,而不是獨立存在的函式庫或軟體開發工具箱。這多少也意味著微軟對 .NET MAUI 未來持續發展的承諾吧。


(太棒了,要買一台 Mac 電腦!😅)


參考資料

沒有留言:

技術提供:Blogger.
回頂端⬆️