2

Following this lecture (https://learn.microsoft.com/en-us/dotnet/core/tutorials/creating-app-with-plugin-support), I managed to create an app based on plugins. So far so good. But, I want to do more with my plugins. Hence, for one of them, I created an additional library. Of course, when developing my plugin, I got a library dependance to this lib I created. The problem is more on execution. When running my app, more especially when the plugin executes its task, I have an exception raised saying:

Could not load file or assembly 'MyLibObjectsLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.

MyLibObjectsLib is of course the additional library used by the called plugin. Is there something I missed?

tripleee
  • 175,061
  • 34
  • 275
  • 318
GLDavid
  • 27
  • 1
  • 5
  • The tutorial you point is working fine in .Net Core, Can you provide the sample project? – M.Hassan Feb 16 '20 at 18:46
  • Hi Hassan,Thanks for your comment. You're right, I had to look closer to the tutorial example. I corrected that by doing in my plugin `code`Assembly acAssembly = typeof(MyLibClass).Assembly; var libType = acAssembly.GetType("System.Data.OleDb.OleDbConnection"); ObjectType instance = (ObjectType)Activator.CreateInstance(libType);`code`and it works like a charm. – GLDavid Feb 18 '20 at 11:56

1 Answers1

5

The tutorial use a custom ALC (AssemblyLoadContext) to load only one plugin assembly which doesn't depend on others.

In your case, the custom ALC load the plugin and resolve all dependencies.

In the custom ALC, you note that it uses AssemblyDependencyResolver ( a new class in .Net Core 3.0+)

The AssemblyDependencyResolver class enables the application developers to more easily develop a plugin architecture in conjunction with custom System.Runtime.Loader.AssemblyLoadContext instances to isolate plugins and also enable plugins to load dependencies.

Important Remark:

Plugins should include ExcludeAssets=runtime for project references to shared assemblies, ref.

For example, If the project Common that include the interface `IContract' and is referenced by the both host application and the plugin project, add reference as given below:

<!-- in the plugin project -->

<ItemGroup>
        <ProjectReference Include="..\IContract\Common.csproj">
            <Private>false</Private>
            <ExcludeAssets>runtime</ExcludeAssets>
        </ProjectReference>
        <ProjectReference Include="..\MyLibObjectsLib\MyLibObjectsLib.csproj" />
    </ItemGroup>

This code is used for loading the plugin:

string pluginPath = @"path/to/MyContract.Plugin.dll";           
var assembly = new PluginLoadContext(pluginPath).LoadFromAssemblyPath(pluginPath);

var type = assembly.GetTypes()
       .FirstOrDefault(t => t.IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);     

if (type != null) {
     var instance = (IContract)Activator.CreateInstance(type);
     var ret = instance.Execute();     
}

I simulated your plugin as standard2.0 library and the plugin reference OLEDB nuget package and the plugin is loaded without errors.

M.Hassan
  • 10,282
  • 5
  • 65
  • 84