您不必以某种特定于平台的方式构建您的自定义.NetStd 程序集。您针对 Xamarin.Essentials .NetStd 参考程序集进行编译,然后捆绑/包含 Xamarin.Essentials 程序集的平台特定,其中包含平台相关的代码。
因此,在运行时,您的自定义 .NetStd 程序集中的类型将被转发/调用到您的应用中已包含的 Xamarin.Essentials 平台特定程序集。
因此,在包含Xamarin.Essentials 的自定义.NetStd 程序集中,将有一个外部程序集定义:
.assembly extern Xamarin.Essentials
{
.ver 1:0:0:0
}
然后在同一个.NetStd 程序集中将是调用程序集中存在的类型的代码,即:OpenAppPackageFileAsync
IL_0030: call [System.Threading.Tasks]System.Threading.Tasks.Task`1<[System.IO]System.IO.Stream> [Xamarin.Essentials]Xamarin.Essentials.FileSystem::OpenAppPackageFileAsync(string)
注意:在 Essentials 的情况下,它不使用 DI/Interfaces 调用平台相关代码,方法 OpenAppPackageFileAsync 调用 PlatformOpenAppPackageFileAsync 方法,并且该方法将在每个方法中包含特定于平台的代码其平台相关程序集。在其基于 .NetStd 的参考组装方法中,它会抛出一个 NotImplementedInReferenceAssemblyException,因为没有通用/通用的基于 .NetStd 的框架代码来实现加载只读应用程序捆绑的 Android/iOS/UWP 文件,即:
.method private hidebysig static [System.Threading.Tasks]System.Threading.Tasks.Task`1<[System.IO]System.IO.Stream>
PlatformOpenAppPackageFileAsync(string filename) cil managed
{
// Code size 6 (0x6)
.maxstack 8
IL_0000: newobj instance void Xamarin.Essentials.NotImplementedInReferenceAssemblyException::.ctor()
IL_0005: throw
} // end of method FileSystem::PlatformOpenAppPackageFileAsync
现在,当您打包/捆绑依赖于平台的应用程序时,例如本例中的 Android,您将不会处理/包含 Essentials 参考程序集,而是特定于平台的版本。
Xamarin.Essentials.dll 程序集的 Android 版本包括 PlatformOpenAppPackageFileAsync 方法:
.method private hidebysig static [mscorlib]System.Threading.Tasks.Task`1<[mscorlib]System.IO.Stream>
PlatformOpenAppPackageFileAsync(string filename) cil managed
{
// Code size 70 (0x46)
.maxstack 3
.locals init ([mscorlib]System.Threading.Tasks.Task`1<[mscorlib]System.IO.Stream> V_0,
[Mono.Android]Java.IO.FileNotFoundException V_1)
IL_0000: ldarg.0
IL_0001: brtrue.s IL_000e
~~~~
.try
{
IL_001d: call [Mono.Android]Android.Content.Context Xamarin.Essentials.Platform::get_AppContext()
IL_0022: callvirt instance [Mono.Android]Android.Content.Res.AssetManager [Mono.Android]Android.Content.Context::get_Assets()
IL_0027: ldarg.0
IL_0028: callvirt instance [mscorlib]System.IO.Stream [Mono.Android]Android.Content.Res.AssetManager::Open(string)
IL_002d: call [mscorlib]System.Threading.Tasks.Task`1<!!0> [mscorlib]System.Threading.Tasks.Task::FromResult<[mscorlib]System.IO.Stream>(!!0)
IL_0032: stloc.0
IL_0033: leave.s IL_0044
~~~