I am working on an MEF plugin using .net core. The plugin uses Entity Framework, and only the plugin project references Entity Framework. I create the CompositionContainer, but when I access the plugin I get this exception:
Could not load file or assembly 'Microsoft.EntityFrameworkCore,
I have a project that defines the Interface:
namespace MyInterfaces
{
public interface IShowMessage
{
void ShowMessage();
}
}
And the Main Project loads the PlugIn:
namespace MainApp
{
public class DoWork
{
private CompositionContainer _container;
[Import(typeof(IShowMessage))]
public IShowMessage MyMessage;
public DoWork()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(GetOtherAssembly()));
_container = new CompositionContainer(catalog);
_container.ComposeParts(this);
MyMessage.ShowMessage();
}
private Assembly GetOtherAssembly()
{
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(Directory.GetCurrentDirectory() + @"\..\..\..\..\MyPlugin\bin\debug\netstandard2.1\MyPlugin.dll");
return assembly;
}
}
}
And a Plugin project that implements the interface:
namespace MyPlugin
{
[Export(typeof(IShowMessage))]
public class ShowComplexMessage : IShowMessage
{
public void ShowMessage()
{
DbSet<String> str;
Console.Write("Complex Message");
}
}
}
The line 'DbSet str;' in the plugin reference EntityFramework. If I comment out this line it works are expected.
I've noticed that the bin folder of my plugin project does not have the EntityFramework dlls. If I use dotnet publish I can generate the EntityFramework dlls, but that does not solve the problem. If I explicitly load 'Microsoft.EntityFrameworkCore'. I get an exception on the ComposeParts line telling me it can't load Assemblies that Entity Framework uses.
I've tried adding all of the DLLs to the catalog, but some fail to load (maybe a binding redirect?). I think I'm going down the wrong path for something common and likely solved. ***EDIT - This is what DirectoryCatalog does, which didn't help. ***
I've also tried creating an instance of the plugin with reflection and I get similar errors.
How do I load an MEF plugin, with of the plugin dependencies?
Please try this:
public class ModuleAssemblyLoadContext : AssemblyLoadContext
{
private readonly AssemblyDependencyResolver resolver;
internal ModuleAssemblyLoadContext(string assemblyPath) : base(true)
{
resolver = new AssemblyDependencyResolver(assemblyPath);
ResolvingUnmanagedDll += OnResolvingUnmanaged;
Resolving += OnResolving;
}
private IntPtr OnResolvingUnmanaged(Assembly assembly, string unmanagedName)
{
string unmanagedPath = resolver.ResolveUnmanagedDllToPath(unmanagedName);
return unmanagedPath != null ? LoadUnmanagedDllFromPath(unmanagedPath) : IntPtr.Zero;
}
private Assembly OnResolving(AssemblyLoadContext context, AssemblyName assemblyName)
{
string assemblyPath = resolver.ResolveAssemblyToPath(assemblyName);
return assemblyPath != null ? LoadFromAssemblyPath(assemblyPath) : null;
}
}
Next in your code:
private Assembly GetOtherAssembly()
{
string path = Directory.GetCurrentDirectory() + @"\..\..\..\..\MyPlugin\bin\debug\netstandard2.1\MyPlugin.dll";
ModuleAssemblyLoadContext context = new ModuleAssemblyLoadContext(path);
return context.LoadFromAssemblyPath(path);
}
Of course, make sure that any dependency your plugin requires is present in the folder where your plugin dll exists.
You may find more complete implementation here:
https://github.com/qube7/qcomposite/blob/master/Qube7.Composite/Hosting/AssemblyModule.cs