Loading System.IO.Ports.dll from dynamically loaded class library in .NET6

Jan Jørgensen 20 Reputation points
2023-02-07T07:36:49.9533333+00:00

Using .net6 or .net7, I can't make a dynamically loaded class library (read plugin) load the System.IO.Ports.dll (nuget package). I'm using VS2022, but had the same problem on .net5 and VS2019. I'm only using Windows.

I have dropped some demonstration code here: https://github.com/JanJorgensen/Net5AddonLoadProblemDemo

Assembly overview

The application loads the plugin like this:

    public static void LoadAndActivateTheAddon()
    {
        var assembly = Assembly.LoadFrom("TheAddon.dll");
        var type = assembly.GetExportedTypes().Where(t => t.Name == "AddonMain").FirstOrDefault();
        object obj = Activator.CreateInstance(type);
        var addon = obj as IAddon;

        addon.Action();     // Call a method in the loaded plugin object.
    }

Exception thrown when trying to create instance of SerialPort class is: System.PlatformNotSupportedException, "System.IO.Ports is currently only supported on Windows."

In .Net Framework (2 through 4.5), it worked perfectly. Maybe because that was only for Windows.

If I create a .net application (console, WinForms or WPF) and use System.IO.Ports directly from that, it works perfectly.

I have tried changing the target framework for the two class libraries from 'net7.0' to 'net7.0-windows' and that didn't help.

While I'm unfortunately not a .net pro, I think there's some details I don't know about building and distributing .net5-7 applications for Windows.

In the output folder, a 'runtimes' folder is created when building, with the Ports assembly in versions for different target systems.

So why can't the dynamically loaded class library load the System.IO.Ports.dll? In a deployed installation it doesn't work either. It seems the plugin assembly should somehow be configured to use the .net7 version of the assembly when on Windows.

I have a dirty solution at the moment, where I add the library as a dependency in my top level application, just to make sure it is loaded, making the plugin work. But that's so ugly and should not be necessary.

I'm stuck on this, so I really hope someone can help me.

(This was also posted on stackoverflow)

.NET Runtime
.NET Runtime
.NET: Microsoft Technologies based on the .NET software framework.Runtime: An environment required to run apps that aren't compiled to machine language.
1,129 questions
{count} votes

Accepted answer
  1. Viorel 112.8K Reputation points
    2023-02-13T01:46:37.6633333+00:00

    There is an example, which is based on .NET 7:

    It seems to work after adding the System.IO.Port code to HelloPlugin. Other sample plug-ins can be removed.

    It uses the AssemblyLoadContext. Maybe you can do something similar. It is not clear if AssemblyLoadContext is crucial.


1 additional answer

Sort by: Most helpful
  1. Bruce (SqlWork.com) 57,401 Reputation points
    2023-02-07T18:24:00.7333333+00:00

    the app hosting the plugin must use the windows only runtime. adding the library reference. try:

       <TargetFramework>net7.0-windows</TargetFramework>
     
    
    0 comments No comments