2

Я пытаюсь использовать PowerShell для вызова кода F #, в котором используются акторы Akka.Net.Почему я получаю MissingMethodException при вызове кода F # из PowerShell?

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 [BOOL] вместо FSharpOption [Boolean]. Я пробовал модифицировать код 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 и отказался от переработанных вещей, поэтому я не называю Akka непосредственно из PowerShell. –

ответ

2

Powershell может быть затруднен, когда дело доходит до соответствия методам, основанным на типах параметров. Я обнаружил, что иногда мне приходится «обманывать» PS, передавая выражение методу, а не переменную PS. Например, $object.method($something.property) вместо $prop = $something.property; $object.method($prop) работал на меня.

В случае перегруженных методов другая вещь, которую вы можете сделать, это использовать Reflection, чтобы убедиться, что у вас есть метод с правильной подписью. Например:

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

А иногда литья помогает: $object.method([typeToMatchMethodSig]$arg1) или, может быть, даже двойной бросок: $object.method([bool][int]$arg1) В обоих случаях я думаю, что вы будете иметь больше удачи, если передать выражение произнесения в качестве аргумента, а не назначать его переменную и передать переменную.

Я сомневаюсь, что это имеет место в OP, но использование [activator] :: createinstance (...) может использоваться с частным конструктором.

Я обычно обманываю его, пока что-то не работает, или я сдаюсь.

BTW, вы можете включить трассировку PS для привязки параметров и получить много информации, которая может быть или не быть полезной.

 Смежные вопросы

  • Нет связанных вопросов^_^