ich in meinem Testlösung 3 Projekte müssen TypeInitializationException:Aufruf F # Bibliothek mit Akka.Net Akteure aus C# Bibliothek führt
- f # Klassenbibliothek (seien wir F # Lib nennen),
- f # -Konsolenanwendung (nennen wir es F # Console) und
- C# Konsolenanwendung (C# -Konsole).
In der Klassenbibliothek ich einen akka.net Schauspieler definieren:
namespace Just.Test.Project
open Akka.Actor
open Akka.FSharp
open Akka.Configuration
module Actors =
let system = System.create "WaveNetSystem" (Configuration.defaultConfig())
let simple = spawn system "simple" (fun mailbox ->
let rec loop() = actor {
let! message = mailbox.Receive()
printfn "%A" message
return! loop()
}
loop()
)
type MainClass(msg) = let x = Actors.simple <! msg
Wenn ich die MainClass
von f # Konsolenanwendung instanziiert, bekomme ich erwartetes Ergebnis:
[<EntryPoint>]
let main argv =
Just.Test.Project.MainClass("bugaga!") |> ignore
System.Threading.Thread.Sleep(1000)
0 // return an integer exit code
Ausgabe:
"bugaga!!!"
Aber. Wenn ich das gleiche von C# Konsolenanwendung tun:
static void Main(string[] args)
{
new Just.Test.Project.MainClass("bugaga!");
System.Threading.Thread.Sleep(1000);
}
Ich erhalte eine Ausnahme:
System.TypeInitializationException: The type initializer for '<StartupCode$SampleFSharpAkkaNet>.$Test' threw an exception. ---> System.MissingMethodException: Method not found: 'Akka.Actor.IActorRef Akka.FSharp.Spawn.spawn(Akka.Actor.IActorRefFactory, System.String, Microsoft.FSharp.Core.FSharpFunc`2<Actor`1<!!0>,Cont`2<!!0,!!1>>)'.
at <StartupCode$SampleFSharpAkkaNet>.$Test..cctor()
--- End of inner exception stack trace ---
at Just.Test.Project.Actors.get_simple()
at Just.Test.Project.MainClass..ctor() in d:\prj\research\AkkaFSharpTest\SampleFSharpAkkaNet\Test.fs:line 20
Wie soll ich diese Ausnahme zu interpretieren? Was könnte falsch sein?
UPDATE
Wie bereits in den Kommentaren und in Tomas Petricek Antwort erwähnt, ist das Problem auf die Versionskonflikt zusammen. Die bindingRedirect
erledigt den Job und alles fängt an zu arbeiten. Aber ich habe immer noch ein Missverständnis.
Zuerst. Die Akka.FSharp
Referenzen FSharp.Core 4.3.1
.
Sekunde. Die F # Lib- und F # -Konsolenreferenzen FSharp.Core 4.4.0
und C# Console haben überhaupt keine Referenzen auf FSharp.Core
.
Dritte. Die F # Konsole funktioniert wie ein Charme, und wenn ich geladen Baugruppen drucke ich bekommen:
FSharpConsole, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
FSharpLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Akka, Version=1.0.6.16, Culture=neutral, PublicKeyToken=null
Akka.FSharp, Version=1.0.6.16, Culture=neutral, PublicKeyToken=null
FsPickler, Version=1.2.21.0, Culture=neutral, PublicKeyToken=null
System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
so, keine FSharp.Core 4.3.1.0
geladen und alles ist tip-top!
Vierte. Die C# -Konsole funktioniert nicht. Die Liste der geladenen Baugruppen sieht ein bisschen seltsam:
CSharpConsole, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
FSharpLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
FSharp.Core, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Akka, Version=1.0.6.16, Culture=neutral, PublicKeyToken=null
Akka.FSharp, Version=1.0.6.16, Culture=neutral, PublicKeyToken=null
Es bedeutet sowohl FSharp.Core, Version=4.4.0.0
und FSharp.Core, Version=4.3.1.0
geladen. Warum? Und warum ist es nicht in F # Console Fall passiert?
SOLUTION
Das Problem (wie sonst üblich)) war in meinem Kopf.
Zunächst einmal habe ich nie in die endgültige F # Console Config geschaut.Die anfängliche app.config
ist ganz einfach:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
aber nach dem Build wird es (dank AutoGenerateBindingRedirects MSBuild flag) die erforderliche buinding umleitet:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.4.0.0" newVersion="4.4.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
die zweite. C# Compiler versucht, mich über das Problem zu informieren, indem solche Nachrichten in der Build-Ausgabe schreiben:
Keine Möglichkeit zur Beilegung von Konflikten zwischen "FSharp.Core, Version = 4.3.1.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a" und "FSharp.Core, Version = 4.3.0.0, Kultur = neutral, PublicKeyToken = b03f5f7f11d50a3a". Wählen Sie "FSharp.Core, Version = 4.3.1.0, Kultur = neutral, PublicKeyToken = b03f5f7f11d50a3a" beliebig. Betrachten Sie das App.config-Remapping der Assembly "FSharp.Core, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a" aus Version "4.3.1.0" [C: \ Programme (x86) \ Reference Assemblies \ Microsoft \ FSharp.NETFramework \ v4.0 \ 4.3.1.0 \ FSharp.Core.dll] bis Version "4.4.0.0" [C: \ Programme (x86) \ Referenz-Assemblys \ Microsoft \ FSharp.NETFramework \ v4.0 \ 4.4.0.0 \ FSharp.Core.dll ] Konflikt zu lösen und Warnung loszuwerden. C: \ Programme (x86) \ MSBuild \ 14.0 \ bin \ Microsoft.Common.CurrentVersion.targets (1820,5): Warnung MSB3276: Konflikte zwischen verschiedenen Versionen derselben abhängigen Assembly gefunden. Setzen Sie die Eigenschaft "AutoGenerateBindingRedirects" in der Projektdatei auf "true". Weitere Informationen finden Sie unter http://go.microsoft.com/fwlink/?LinkId=294190.
Aber ich entschied, dass C# -Compiler nur ein wenig restriktiver als F # -Compiler ist. Ich wusste nicht, dass in F # -Projekten die Flagge automatisch gesetzt wird. Was hat mich davon abgehalten, es zu überprüfen? Ich weiß es nicht!)
Sie haben verschiedene Versionen einiger Bibliotheken, auf die in verschiedenen Projekten verwiesen wird. –
Ausnahmebedingungen besagt, dass die Spawn-Methode in C# App nicht erkannt wurde. Verfügen Sie über Akka.FSharp- und FSharp.Core-Assemblys, auf die in Ihrem C# -Projekt verwiesen wird? – Horusiath
@horusiath Es ist, was ich auch dachte, aber nein, alles sieht hier korrekt aus. –