У меня такая ситуация:
uap10.0.16299).Есть ли способ обойти это? Или мне также нужно создать версию X для UWP? Причина, по которой я избегал этого до сих пор, заключается в том, что тогда у меня будут одни цели, которые я могу построить только в Windows, а другие - только на Mac.





Дело не в том, что вам нужно строить вашей пользовательской сборки .NetStd каким-либо образом, зависящим от платформы. Вы компилируете против эталонную сборку Xamarin.Essentials .NetStd, а затем связать / включить специфичную для платформы сборку Xamarin.Essentials, которая включает код, зависящий от платформы.
Таким образом, в время выполнения типы в вашей пользовательской сборке .NetStd будут перенаправлены / вызваны в сборку, специфичную для платформы Xamarin.Essentials, которая была включена в ваше приложение.
Итак, в вашей пользовательской сборке .NetStd, которая включает Xamarin.Essentials, будет определение внешней сборки:
.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
~~~
@ E.Bishop Правильно, каждое хост-приложение должно включать / связывать "специальную" платформо-зависимую версию сборки, которая "соответствует" эталонной сборке (.assembly Name / Version / Types included / ...), которую вы скомпилировали библиотека .NetStd, которая содержит ваш пользовательский код для
К сожалению, насколько я могу судить, на практике это не работает. После добавления пакета Xamarin.Essentials непосредственно в мое хост-приложение кажется, что он все еще получает код .NET Standard от Xamarin.Essentials, когда он вызывается из библиотеки классов, о чем свидетельствует получение NotImplementedInReferenceAssemblyException.
@ E.Bishop Что такое платформа хост-приложения?
Ой, подождите ... Я думал, что это проект UWP, но на самом деле это был .NET 4.6. Я попробую еще раз с UWP.
Что ж, теперь я вижу другую проблему: это не позволяет мне вообще добавить мой пакет NuGet в проект UWP. Жалуется, что пакет несовместим с uap10.0.15063. Пакет имеет целевые значения netstandard1.4, netstandard1.6, netstandard2.0 и net45; Разве один из них не должен быть совместим с UWP?
@ E.Bishop UWP и NetStandard 2.0 в Windows 10 Fall Creators Update и более поздних версиях
Я не могу следить за байт-кодом в ваших примерах, но правильно ли я понимаю, что ответ в основном таков: явно включить
Xamarin.Essentialsв хост-приложение, а не просто полагаться на транзитивную зависимость от него из моей библиотеки классов?