Search code examples
c#plugins.net-6.0

Plugin Model instantiate two plugins with same name but diff versions System.IO.FileLoadException: Assembly with same name is already loaded


I have a plugin model in an .NET 6 app. I have a list of "environments" each of whose configuration contains a plugin to instantiate.

{
    Environments:[
        { 
          EnvironmentName:"abc1",
          PluginName:"plugin1\\abcplugin,myplugin"  <- v1.0.0.0
        },
        { 
          EnvironmentName:"abc2",
          PluginName:"plugin2\\abcplugin,myplugin"  <- v2.0.0.0
        },
    ]
}

I loop through the environments running the plugins.

The code for each plugin is in its own separate folder.

In folder plugin1 I have abcplugin.dll v1.0.0.0 In folder plugin2 I have abcplugin.dll v2.0.0.0

Which ever plugin I load second I get an error when executing Assembly.LoadFrom():

System.IO.FileLoadException: Assembly with same name is already loaded

Is there a way to get around this issue?

Here's the code I use to instantiate it:

public static ISyncPlugin Create(string assemblyName, string typeName, INotificationService notificationService)
{
    var path = Assembly.GetExecutingAssembly().Location; // path of currently running assembly with dll extension
    path = path.Substring(0, path.LastIndexOf('\\') + 1); // strip filename
    path = path + Constants.PLUGIN_FOLDER + assemblyName + ".dll"; // add plugin folder and assembly name of plugin to instantiate

    if (!File.Exists(path))
    {
        notificationService.LogError($"SyncPluginFactory could not find plugin assembly at {path} - please check the spelling:");
        return null;
    }

    var asm = Assembly.LoadFrom(path);

    if (assemblyName.Contains('\\'))
    {
        assemblyName = assemblyName.Substring(assemblyName.LastIndexOf('\\') + 1); // strip off folder name
    }

    var type = asm.GetType(assemblyName + "." + typeName);

    if (type == null)
    {
        notificationService.LogError($"SyncPluginFactory cannot find {assemblyName} {typeName}- please check the spelling");
        return null;
    }

    ISyncPlugin plugin;
    try
    {
        plugin = (ISyncPlugin)Activator.CreateInstance(type);
        var fvi = FileVersionInfo.GetVersionInfo(path);
        notificationService.LogDebug($"Plugin {assemblyName}.{typeName} instantiated successfully - version {fvi.FileVersion}");
    }
    catch (Exception e)
    {
        notificationService.LogError($"SyncPluginFactory cannot instantiate {assemblyName} {typeName}- please check the spelling: {e}");

        return null;
    }


    return plugin;
}

Solution

  • By changing the following line:

    var asm = Assembly.LoadFrom(path);
    

    To :

    var asm = Assembly.LoadFile(path);
    

    I am able to load and execute the plugins with same name but different versions.