Problem mit modularer Architektur

  • C#

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von DTF.

    Problem mit modularer Architektur

    Hi,

    ich habe ein bestehendes Konsolenprogramm das auf Windows und Linux läuft(TargetFramework NET6), dieses soll nun eine GUI bekommen. Die GUI ist in einer DLL welche zur Laufzeit geladen wird(optionales Plugin), die Window GUI braucht dann aber TargetFramework NET6-Windows. Für Linux ist keine GUI geplant. Wenn ich mit dieser Konfiguration das Programm starte bekomme ich diese Exception sobald die Windows-GUI-Dll geladen wird:

    System.Reflection.ReflectionTypeLoadException: "Unable to load one or more of the requested types.
    Could not load file or assembly 'PresentationFramework, Version=6.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.


    Ich denke das passiert weil die KonsolenApp das TargetFramework NET6 hat also ohne Windows und das mir deswegen alles um die Ohren fliegt(use WPF muss für Linux ja auch false sein). Kann man da irgendwie tricksen ohne die Runtime mitzuliefern? Oder sollte ich besser umdenken und die GUI als EXE kompileren und die beiden Programme via Pipes kommunizieren lassen?
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „DTF“ ()

    ChatGPT sagt folgendes:
    "Es scheint, dass die Windows GUI-DLL eine Abhängigkeit von der Windows-spezifischen PresentationFramework-Assembly hat, die in einer NET6-Windows-Umgebung verfügbar ist, aber nicht in einer NET6-Umgebung ohne Windows. Eine Möglichkeit, dieses Problem zu umgehen, ist, die GUI als separate EXE-Datei zu kompilieren und sie über eine Pipe-Kommunikation mit der Konsolenanwendung zu verbinden, wie Sie vorschlagen.

    Eine andere Option besteht darin, Ihre Windows-spezifische GUI-DLL in einer separaten NET6-Windows-Assembly zu kompilieren und sie nur zur Laufzeit in der Windows-Umgebung zu laden. Sie können dies tun, indem Sie die GUI-Funktionalität in eine separate Bibliothek auslagern und sie in beiden Projekten referenzieren. Sie können dann mithilfe von Reflection prüfen, ob die PresentationFramework-Assembly verfügbar ist, bevor Sie versuchen, die GUI-DLL zu laden.

    Eine dritte Möglichkeit besteht darin, die GUI-Funktionalität vollständig auf die Linux-Seite zu verlagern und eine plattformübergreifende GUI-Bibliothek wie GTK# oder Qt zu verwenden, die sowohl unter Windows als auch unter Linux ausgeführt werden kann.

    Letztendlich hängt die beste Option von den Anforderungen und Einschränkungen Ihres Projekts ab."
    Die DLLs für die GUI sind ja NET6-Windows, der Rest NET6(ohne-Windows)

    In etwa habe ich ja option 2, Die Konsolenanwendung die auf beiden Betriebssystem laufen kann(1 EXE + zig Plugin DLLs, alles NET6), dazu die PluginDll für Windows(NET6-Windows). Dazu dann 5 DLLs für die GUI(MVVM auf mehrere Projekte verteilt), das soll dann in der Plugin DLL geladen werden, wenn das OS denn Windows ist. Eigendlich ist die PresentationFramework ja vorhanden, kann aber nicht gefunden werden, ich denke das da der Pfad PF-Dll nicht bekannt ist, weil die EXE nur "NET6" ist, da ist halt nur diese Laufzeit geladen.
    Das "GuiProject" bzw. Projekte müssen in der Konsolen App unbekannt bleiben, sonst wäre das ja kein Plugin.

    Ein Auszug aus dem Code wie ich alle Dlls(Plugins lade): die PluginDll die die DLL der View verwenden soll habe ich zum testen mit NET6 und NET6-windows kompiliert, auch mit verschiedenen SDKs habs ich das versucht. Da sieht man gut wie ich auch zwischen den Betriebssystem unterscheide. (ja ich werde die redundanz noch entfernen)

    C#-Quellcode

    1. public void LoadPlugins()
    2. {
    3. if(System.IO.Directory.Exists(CommonPluginsDirectory))
    4. {
    5. foreach (string dll in System.IO.Directory.GetFiles(CommonPluginsDirectory, "*.dll"))
    6. {
    7. Assembly assembly = Assembly.LoadFrom(dll);
    8. foreach (Type type in assembly.GetTypes())
    9. {
    10. if ((type.IsSubclassOf(typeof(IPlugin)) || type.GetInterfaces().Contains(typeof(IPlugin))) && type.IsAbstract == false)
    11. {
    12. IPlugin plugin = type.InvokeMember(null, BindingFlags.CreateInstance, null, null, null) as IPlugin;
    13. LoadedPlugins.Add(plugin.Name, new PluginModel(plugin));
    14. Logger.Info("Loaded Common-Plugin: " + plugin.Name);
    15. }
    16. }
    17. }
    18. }
    19. if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && System.IO.Directory.Exists(WindowsPluginDirectory))
    20. {
    21. foreach (string dll in System.IO.Directory.GetFiles(WindowsPluginDirectory, "*.dll"))
    22. {
    23. Assembly assembly = Assembly.LoadFrom(dll);
    24. foreach (Type type in assembly.GetTypes())
    25. {
    26. if ((type.IsSubclassOf(typeof(IPlugin)) || type.GetInterfaces().Contains(typeof(IPlugin))) && type.IsAbstract == false)
    27. {
    28. IPlugin plugin = type.InvokeMember(null, BindingFlags.CreateInstance, null, null, null) as IPlugin;
    29. LoadedPlugins.Add(plugin.Name, new PluginModel(plugin));
    30. Logger.Info("Loaded Windows-Plugin: " + plugin.Name);
    31. }
    32. }
    33. }
    34. }
    35. //.....................
    36. }


    Ich vermute mal das hängt mit der geladenen Laufzeit der EXE zusammen, wir haben ja bei NET6 die Appname.runtimeconfig.json, dadrin ist ja die zu ladende Laufzeit festgelegt:
    Edit: habe die RuntimeConfig.json mal editiert und die EXE per doppelklick gestartet, aber bleibt beim Fehler. Liegt wohl am festgelegt Framework der EXE. ( in *.csproj)

    Quellcode

    1. {
    2. "runtimeOptions": {
    3. "tfm": "net6.0",
    4. "framework": {
    5. "name": "Microsoft.NETCore.App",
    6. "version": "6.0.0"
    7. }
    8. }
    9. }

    Editierte JSON:
    Spoiler anzeigen

    Quellcode

    1. {
    2. "runtimeOptions": {
    3. "tfm": "net6.0",
    4. "frameworks": [
    5. {
    6. "name": "Microsoft.NETCore.App",
    7. "version": "6.0.0"
    8. },
    9. {
    10. "name": "Microsoft.WindowsDesktop.App",
    11. "version": "6.0.0"
    12. }
    13. ]
    14. }
    15. }


    Ich denke in der PluginDLl für Windows werde ich dann einfach das Zeug mit den Pipes reinmachen, die GUI dann als exe. Ich denke das ist die einfachste Lösung.
    Bilder
    • Unbenannt.jpg

      208,74 kB, 1.179×403, 44 mal angesehen
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „DTF“ ()