MEF - 加载依赖项
MEF - Loading dependencies
我正在使用 .net 核心开发 MEF 插件。该插件使用 Entity Framework,并且只有插件项目引用 Entity Framework。我创建了 CompositionContainer,但是当我访问该插件时出现此异常:
Could not load file or assembly 'Microsoft.EntityFrameworkCore,
我有一个定义接口的项目:
namespace MyInterfaces
{
public interface IShowMessage
{
void ShowMessage();
}
}
主项目加载插件:
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;
}
}
}
以及实现该接口的插件项目:
namespace MyPlugin
{
[Export(typeof(IShowMessage))]
public class ShowComplexMessage : IShowMessage
{
public void ShowMessage()
{
DbSet<String> str;
Console.Write("Complex Message");
}
}
}
插件参考 EntityFramework 中的行 'DbSet str;'。如果我注释掉这一行,它会正常工作。
我注意到我的插件项目的 bin 文件夹没有 EntityFramework dll。如果我使用 dotnet publish,我可以生成 EntityFramework dll,但这并不能解决问题。
如果我显式加载 'Microsoft.EntityFrameworkCore'。我在 ComposeParts 行上遇到异常,告诉我它无法加载 Entity Framework 使用的程序集。
我已经尝试将所有 DLL 添加到目录中,但有些无法加载(可能是绑定重定向?)。我认为我正在为一些常见且可能已解决的问题走上错误的道路。 ***编辑——这就是 DirectoryCatalog 所做的,但没有帮助。 ***
我也尝试过使用反射创建插件实例,但我遇到了类似的错误。
如何使用插件依赖项加载 MEF 插件?
请试试这个:
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;
}
}
您的代码中的下一个:
private Assembly GetOtherAssembly()
{
string path = Directory.GetCurrentDirectory() + @"\..\..\..\..\MyPlugin\bin\debug\netstandard2.1\MyPlugin.dll";
ModuleAssemblyLoadContext context = new ModuleAssemblyLoadContext(path);
return context.LoadFromAssemblyPath(path);
}
当然,请确保插件所需的任何依赖项都存在于插件 dll 所在的文件夹中。
您可以在此处找到更完整的实现:
https://github.com/qube7/qcomposite/blob/master/Qube7.Composite/Hosting/AssemblyModule.cs
我正在使用 .net 核心开发 MEF 插件。该插件使用 Entity Framework,并且只有插件项目引用 Entity Framework。我创建了 CompositionContainer,但是当我访问该插件时出现此异常:
Could not load file or assembly 'Microsoft.EntityFrameworkCore,
我有一个定义接口的项目:
namespace MyInterfaces
{
public interface IShowMessage
{
void ShowMessage();
}
}
主项目加载插件:
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;
}
}
}
以及实现该接口的插件项目:
namespace MyPlugin
{
[Export(typeof(IShowMessage))]
public class ShowComplexMessage : IShowMessage
{
public void ShowMessage()
{
DbSet<String> str;
Console.Write("Complex Message");
}
}
}
插件参考 EntityFramework 中的行 'DbSet str;'。如果我注释掉这一行,它会正常工作。
我注意到我的插件项目的 bin 文件夹没有 EntityFramework dll。如果我使用 dotnet publish,我可以生成 EntityFramework dll,但这并不能解决问题。 如果我显式加载 'Microsoft.EntityFrameworkCore'。我在 ComposeParts 行上遇到异常,告诉我它无法加载 Entity Framework 使用的程序集。
我已经尝试将所有 DLL 添加到目录中,但有些无法加载(可能是绑定重定向?)。我认为我正在为一些常见且可能已解决的问题走上错误的道路。 ***编辑——这就是 DirectoryCatalog 所做的,但没有帮助。 ***
我也尝试过使用反射创建插件实例,但我遇到了类似的错误。
如何使用插件依赖项加载 MEF 插件?
请试试这个:
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;
}
}
您的代码中的下一个:
private Assembly GetOtherAssembly()
{
string path = Directory.GetCurrentDirectory() + @"\..\..\..\..\MyPlugin\bin\debug\netstandard2.1\MyPlugin.dll";
ModuleAssemblyLoadContext context = new ModuleAssemblyLoadContext(path);
return context.LoadFromAssemblyPath(path);
}
当然,请确保插件所需的任何依赖项都存在于插件 dll 所在的文件夹中。
您可以在此处找到更完整的实现:
https://github.com/qube7/qcomposite/blob/master/Qube7.Composite/Hosting/AssemblyModule.cs