2

我想使用PowerShell調用一些使用Akka.Net actor的F#代碼。爲什麼在從PowerShell調用F#代碼時收到MissingMethodException?

的F#代碼工作正常的單元測試,並從F#解釋器中運行時,但是當我把相同的代碼從PowerShell命令我得到以下異常:

System.MissingMethodException: Method not found: 'Void Nessos.FsPickler.BinarySerializer..ctor(Microsoft.FSharp.Core.FSharpOption`1<Boolean>, 
        Microsoft.FSharp.Core.FSharpOption`1<Nessos.FsPickler.ITypeNameConverter>)'. 
         at Akka.FSharp.Serialization.ExprSerializer..ctor(ExtendedActorSystem system) 
         at Akka.FSharp.Serialization.exprSerializationSupport(ActorSystem system) 
         at Namespace.NewActorCmdlet..ctor(Host hostA, Host hostB, Boolean option, UserDetails user) in 
        E:\Projects\Namespace\NewActorCommand.fs:line 24 
         at Namespace.StartNewActorCommand.ProcessRecord() in 
        E:\Projects\Namespace\StartNewActor.fs:line 67 
         at System.Management.Automation.CommandProcessor.ProcessRecord() 

我試圖在運行[Nessos.FsPickler.BinarySerializer]::new.OverloadDefinitions PowerShell會話檢查什麼方法PS雖然空出來了,我得到:

Nessos.FsPickler.BinarySerializer new(Microsoft.FSharp.Core.FSharpOption[bool] forceLittleEndian, Microsoft.FSharp.Core.FSharpOption[Nessos.FsPickler.ITypeNameConverter] typeConverter) 

我注意到的第一件事是,通過PowerShell中顯示的版本需要一個FSharpOption [布爾]而不是FSharpOption [布爾]。我嘗試修改Akka.FSharp代碼以顯式傳遞選項,但這似乎沒有幫助。

我使用FSharp.Core 4.0.0.1(其他鏈接建議3.0有問題)。

有沒有人見過類似的東西?

甚至有關在哪裏尋找問題的建議都會有所幫助,我不確定問題出在PowerShell,F#或Akka.Net上。

+4

根據我的經驗'MissingMethodException'總是由版本問題引起的。您的PowerShell會話很可能最終會加載一個不同於您的代碼最初編譯的程序集版本。你最好的選擇是使用fuslogvw解決程序集綁定問題https://msdn.microsoft.com/en-us/library/e74a18c4 –

+0

fuslogvw原來是一個好的開始。沒有解決問題,但讓我至少診斷一下。 原來,Akka.FSharp和FsPickler是針對不同版本的FSharp.Core構建的。在常規項目中,您可以使用綁定重定向的魔術來掩蓋這些差異,但在PowerShell中這不是那麼容易。 最後我遵循@ user2470798和的建議放棄了重新設計的東西,所以我不直接從PowerShell調用Akka。 –

回答

2

當涉及到基於參數類型的匹配方法時,Powershell會很困難。我發現有時我必須通過向表達式傳遞一個方法而不是PS變量來「欺騙」PS。例如$object.method($something.property)而不是$prop = $something.property; $object.method($prop)已經爲我工作。

在重載方法的情況下,您可以做的另一件事是使用反射來確保您擁有正確簽名的方法。例如:

$mi=$object.gettype().getmethod('TheMethod',@([typeParm1],[typeParm2])) 
$mi.invoke($object, @($arg1,$arg2)) 

有時鑄造幫助:$object.method([typeToMatchMethodSig]$arg1)或者甚至一個雙投:$object.method([bool][int]$arg1)在這兩種情況下,我認爲你有更多的運氣,如果你通過投表達式作爲參數,而不是將其分配到一個變量並傳遞變量。

我懷疑這是OP的情況,但使用[activator] :: createinstance(...)可以與私有構造函數一起使用。

我通常會把它弄糊塗,直到有些東西能奏效,或者我放棄。

順便說一句,你可以打開PS跟蹤參數綁定,並獲得大量的信息,這可能會或可能不會有用。

相關問題