使用带有 F# 和 ReactiveUI 的 Xamarin Android 时出现运行时错误
Runtime error using Xamarin Android with F# and ReactiveUI
我创建了一个使用 F# 和 ReactiveUI 的 Xamarin Android 项目。
加载我的仪表板时,我在此代码段的 inherit
行遇到运行时异常(MissingMethodException
类型):
type DashboardViewModel(?host: IScreen) =
inherit ReactiveViewModel()
let host = LocateIfNone host
member __.Title with get() = "Dashboard"
interface IRoutableViewModel with
member __.HostScreen = host
member __.UrlPathSegment = "Dashboard"
错误消息显示为
Method 'Microsoft.FSharp.Quotations.FSharpExpr.Deserialize40' not found.
ReactiveViewModel
类型是 ReactiveObject
的薄包装:
type ReactiveViewModel() as this =
inherit ReactiveObject()
let mutable message = noMessage
let uiContext = SynchronizationContext.Current
member __.SyncContext with get() = uiContext
member this.Message
with get() = message
and set(value) =
this.RaiseAndSetIfChanged(&message, value, "Message") |> ignore
if message <> noMessage then this.RaiseAndSetIfChanged(&message, noMessage, "Message") |> ignore
member val MessageSent =
this.WhenAnyValue(toLinq <@ fun vm -> vm.Message @>).ObserveOn(RxApp.MainThreadScheduler).Where(fun m -> m <> noMessage) with get
该项目是开源的:目前,它包含的内容很少。它可以在 https://github.com/SpiegelSoft/Astrid.
找到
我已在 Xamarin 错误跟踪器上提交错误:https://bugzilla.xamarin.com/show_bug.cgi?id=51000
有没有我可以自己实施的已知修复程序,以便我可以自行关闭错误?
更新 1
这个周末我一直在调查这个问题。
加载的FSharp.Core版本卡在过时版本2.3.98.1上。这对应于
中的 FSharp.Core.dll
文件
C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework\MonoAndroid\v1.0
我已尝试删除此版本并加载 NuGet 包 FSharp.Core;然而,当我构建 Android 项目时,路径总是恢复到参考程序集路径中的过时文件。
有没有办法覆盖这种行为?
更新 2
替换Reference Assemblies
路径下的FSharp.Core.dll
文件可以解决问题,但这是一个非常不理想的橡皮膏,我不能要求我的用户应用。理想情况下,我想找到一种方法来防止 .Droid
项目从 GAC 而不是 NuGet 包加载 FSharp.Core
。
前几天我 运行 遇到了一个非常相似的问题。我的 android 应用程序引用了 Profile7 F# PCL 库,它使用了 List.unfold,我相信它是在 F# 4 中引入的。当我在我的应用程序中使用该库时,我看到类似于您所看到的 MissingMethodException。 Xamarin 在创建新的 Android 应用程序时默认引用的 FSharp.Core 版本没有这个更新的方法。我通过编辑应用程序的 .fsproj 文件以删除对 FSharp.Core 的原始引用并将其替换为对较新版本的引用(我 copy/pasted 来自 PCL.fsproj 文件)。它看起来像这样:
<Reference Include="FSharp.Core">
<Name>FSharp.Core</Name>
<Private>True</Private>
<AssemblyName>FSharp.Core.dll</AssemblyName>
<HintPath>$(MSBuildExtensionsPath32)\..\Reference Assemblies\Microsoft\FSharp\.NETCore$(TargetFSharpCoreVersion)\FSharp.Core.dll</HintPath>
</Reference>
我惊讶地发现这似乎解决了我的问题。我不确定我是否会 运行 解决其他问题,但如果你还没有尝试的话可能值得一试。
更新 如果这不能立即奏效,请按照 Rob Lyndon 的回答中的步骤顺序进行操作。
这似乎已被 GitHub 提交
修复
https://github.com/xamarin/xamarin-android/commit/df41af046000556ed82f638e8041b7f718966a92
从框架程序集列表中删除 FSharp.Core,并允许在不替换 NuGet FSharp.Core 程序集的情况下构建项目。
在将此修复程序发布到 SDK 之前,有一个解决方法。 user3850711 提交的答案有效,但您需要按特定顺序应用更改,否则引用将在构建过程中被覆盖。
- 删除对
FSharp.Core
的现有引用。
- 安装或重新安装
FSharp.Core
NuGet 包。
- 卸载项目并将
<HintPath>packages\FSharp.Core.4.0.0.1\lib\portable-net45+monoandroid10+monotouch10+xamarinios10\FSharp.Core.dll</HintPath>
添加到 FSharp.Core
项目引用。
我创建了一个使用 F# 和 ReactiveUI 的 Xamarin Android 项目。
加载我的仪表板时,我在此代码段的 inherit
行遇到运行时异常(MissingMethodException
类型):
type DashboardViewModel(?host: IScreen) =
inherit ReactiveViewModel()
let host = LocateIfNone host
member __.Title with get() = "Dashboard"
interface IRoutableViewModel with
member __.HostScreen = host
member __.UrlPathSegment = "Dashboard"
错误消息显示为
Method 'Microsoft.FSharp.Quotations.FSharpExpr.Deserialize40' not found.
ReactiveViewModel
类型是 ReactiveObject
的薄包装:
type ReactiveViewModel() as this =
inherit ReactiveObject()
let mutable message = noMessage
let uiContext = SynchronizationContext.Current
member __.SyncContext with get() = uiContext
member this.Message
with get() = message
and set(value) =
this.RaiseAndSetIfChanged(&message, value, "Message") |> ignore
if message <> noMessage then this.RaiseAndSetIfChanged(&message, noMessage, "Message") |> ignore
member val MessageSent =
this.WhenAnyValue(toLinq <@ fun vm -> vm.Message @>).ObserveOn(RxApp.MainThreadScheduler).Where(fun m -> m <> noMessage) with get
该项目是开源的:目前,它包含的内容很少。它可以在 https://github.com/SpiegelSoft/Astrid.
找到我已在 Xamarin 错误跟踪器上提交错误:https://bugzilla.xamarin.com/show_bug.cgi?id=51000
有没有我可以自己实施的已知修复程序,以便我可以自行关闭错误?
更新 1
这个周末我一直在调查这个问题。
加载的FSharp.Core版本卡在过时版本2.3.98.1上。这对应于
中的FSharp.Core.dll
文件
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v1.0
我已尝试删除此版本并加载 NuGet 包 FSharp.Core;然而,当我构建 Android 项目时,路径总是恢复到参考程序集路径中的过时文件。
有没有办法覆盖这种行为?
更新 2
替换Reference Assemblies
路径下的FSharp.Core.dll
文件可以解决问题,但这是一个非常不理想的橡皮膏,我不能要求我的用户应用。理想情况下,我想找到一种方法来防止 .Droid
项目从 GAC 而不是 NuGet 包加载 FSharp.Core
。
前几天我 运行 遇到了一个非常相似的问题。我的 android 应用程序引用了 Profile7 F# PCL 库,它使用了 List.unfold,我相信它是在 F# 4 中引入的。当我在我的应用程序中使用该库时,我看到类似于您所看到的 MissingMethodException。 Xamarin 在创建新的 Android 应用程序时默认引用的 FSharp.Core 版本没有这个更新的方法。我通过编辑应用程序的 .fsproj 文件以删除对 FSharp.Core 的原始引用并将其替换为对较新版本的引用(我 copy/pasted 来自 PCL.fsproj 文件)。它看起来像这样:
<Reference Include="FSharp.Core">
<Name>FSharp.Core</Name>
<Private>True</Private>
<AssemblyName>FSharp.Core.dll</AssemblyName>
<HintPath>$(MSBuildExtensionsPath32)\..\Reference Assemblies\Microsoft\FSharp\.NETCore$(TargetFSharpCoreVersion)\FSharp.Core.dll</HintPath>
</Reference>
我惊讶地发现这似乎解决了我的问题。我不确定我是否会 运行 解决其他问题,但如果你还没有尝试的话可能值得一试。
更新 如果这不能立即奏效,请按照 Rob Lyndon 的回答中的步骤顺序进行操作。
这似乎已被 GitHub 提交
修复https://github.com/xamarin/xamarin-android/commit/df41af046000556ed82f638e8041b7f718966a92
从框架程序集列表中删除 FSharp.Core,并允许在不替换 NuGet FSharp.Core 程序集的情况下构建项目。
在将此修复程序发布到 SDK 之前,有一个解决方法。 user3850711 提交的答案有效,但您需要按特定顺序应用更改,否则引用将在构建过程中被覆盖。
- 删除对
FSharp.Core
的现有引用。 - 安装或重新安装
FSharp.Core
NuGet 包。 - 卸载项目并将
<HintPath>packages\FSharp.Core.4.0.0.1\lib\portable-net45+monoandroid10+monotouch10+xamarinios10\FSharp.Core.dll</HintPath>
添加到FSharp.Core
项目引用。