前言
如果您是第一次創建MAUI項目, 并且在之前也并沒有接觸過Xamarin.Forms應用, 或許你并不知道MAUI的強大優勢, 在原來的Xamarin.Forms當中, 我們基于不同平臺的項目他們是單獨維護的。
如下所示:
因為如此, 你需要維護不同平臺的項目。包括每個項目當中包含的資源、圖像、屬性定義, Nuget包引用, 都需要保持一致。
在MAUI項目當中, 你不會再存在類似的問題, .NET MAUI 相比Xamarin.Forms 最大的區別就在于, MAUI是單個項目支持多個平臺。MAUI 應用的項目包含 一個 Platform 文件夾,每個子文件夾都表示 .NET MAUI 可以面向的平臺:
每個文件夾代表了每個平臺特定的代碼, 在默認的情況下 編譯階段僅僅會編譯當前選擇的平臺文件夾代碼。
當你選擇編譯Windows平臺的時候,Android、IOS等文件夾會忽略編譯階段,僅編譯Windows平臺相關代碼, 同理其他平臺也是一樣。
這個時候, 我們可能就存在一個問題, 既然一個項目包含了這么多平臺的代碼, 那么它應該怎么區分哪些代碼屬于哪個平臺?
這也正是MAUI項目默認通過文件夾來區分平臺定義的方式, 那是不是還有別的方式來區分不同平臺的代碼?確實有的, 我們還可以通過文件名定義的方式來區分不同平臺。
基于文件名的多目標
為了能夠讓VisualStudio 區分當前編譯的平臺中, 哪些代碼應該被編譯, 哪些代碼應該被忽略, 所以我們通過文件的結尾命名來區分。在這里, 首先我們需要在項目中添加以下XML代碼
<ItemGroup Condition="$(TargetFramework.StartsWith('net6.0-android')) != true"><Compile Remove="**\**\*.Android.cs" /><None Include="**\**\*.Android.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" /></ItemGroup><ItemGroup Condition="$(TargetFramework.StartsWith('net6.0-ios')) != true AND $(TargetFramework.StartsWith('net6.0-maccatalyst')) != true"><Compile Remove="**\**\*.iOS.cs" /><None Include="**\**\*.iOS.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" /></ItemGroup><ItemGroup Condition="$(TargetFramework.Contains('-windows')) != true "><Compile Remove="**\*.Windows.cs" /><None Include="**\*.Windows.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" /></ItemGroup>
選擇當前的項目, 右鍵編輯項目文件, 添加如上所示的代碼即可。
該XML的主要作用是將生成系統配置為在特定條件下刪除基于平臺的文件名模式:
不要編譯文件名以 .Android 結尾的 C# 代碼。cs,如果不為Android生成。
不要編譯文件名以 .iOS 結尾的 C# 代碼。cs,如果未為 iOS 或 MacCatalyst 生成。
不要編譯文件名以 .Windows 結尾的 C# 代碼。cs,如果不為Windows生成。
配置完成后, 我們就可以不必在Platform文件夾中去單獨定義了, 我們隨便編寫一個Services文件夾, 添加基于不同平臺的模擬代碼。
在實現的代碼當中, 我們模擬在方法中創建基于不同平臺的進度條控件。
public interface ILocalService{void GetValue(string key);}//Androidpartial class LocalService : ILocalService{public void GetValue(string key){new Android.Widget.ProgressBar(null);}}//IOSpartial class LocalService : ILocalService{public void GetValue(string key){new UIKit.UIProgressView();}}//Windowspartial class LocalService : ILocalService{public void GetValue(string key){new ProgressBar();}}
同時, 基于文件夾的多目標可以與基于文件名的多目標組合在一起。?
總結
這一節, 主要是介紹了MAUI當中的單項目支持多目標平臺, 以及與傳統的Xamarin.Forms的差異, 在下一節中, 則會介紹MAUI當中的依賴注入, 以及針對Xamarin.Forms的差異進行詳細對比。